From 2636f510776da83d66fa7aca3d7041e8131526ca Mon Sep 17 00:00:00 2001 From: bakk Date: Tue, 18 May 2021 17:49:31 +0200 Subject: [PATCH] Lex special symbols as one token --- kalk/src/lexer.rs | 9 ++++++++- kalk/src/parser.rs | 8 ++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/kalk/src/lexer.rs b/kalk/src/lexer.rs index cc4cca2..dede2cf 100644 --- a/kalk/src/lexer.rs +++ b/kalk/src/lexer.rs @@ -116,6 +116,13 @@ impl<'a> Lexer<'a> { ';' => build(TokenKind::Semicolon, "", span), '%' => build(TokenKind::Percent, "", span), '\'' => build(TokenKind::Tick, "", span), + // Some of the special symbols will be lexed here, + // so that they don't merge with other symbols. + 'π' => build(TokenKind::Identifier, "π", span), + '√' => build(TokenKind::Identifier, "√", span), + 'τ' => build(TokenKind::Identifier, "τ", span), + 'ϕ' => build(TokenKind::Identifier, "ϕ", span), + 'Γ' => build(TokenKind::Identifier, "Γ", span), _ => build(TokenKind::Unknown, "", span), }; @@ -221,7 +228,7 @@ fn is_valid_identifier(c: Option<&char>) -> bool { if let Some(c) = c { match c { '+' | '-' | '/' | '*' | '%' | '^' | '!' | '(' | ')' | '=' | '.' | ',' | ';' | '|' - | '⌊' | '⌋' | '⌈' | '⌉' | ']' => false, + | '⌊' | '⌋' | '⌈' | '⌉' | ']' | 'π' | '√' | 'τ' | 'ϕ' | 'Γ' => false, _ => !c.is_digit(10), } } else { diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index 8eb4d4f..e77925d 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -481,10 +481,14 @@ fn parse_identifier(context: &mut Context) -> Result { let identifier = Identifier::from_full_name(&advance(context).value); // Eg. sqrt64 - if match_token(context, TokenKind::Literal) { + if match_token(context, TokenKind::Literal) + || peek(context).value == "π" + || peek(context).value == "τ" + || peek(context).value == "ϕ" + { // If there is a function with this name, parse it as a function, with the next token as the argument. if context.symbol_table.contains_fn(&identifier.pure_name) { - let parameter = Expr::Literal(string_to_num(&advance(context).value)); + let parameter = parse_primary(context)?; return Ok(Expr::FnCall(identifier, vec![parameter])); } }