aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
authorTolmachev Igor <me@igorek.dev>2026-05-09 15:25:49 +0300
committerTolmachev Igor <me@igorek.dev>2026-05-09 15:38:35 +0300
commit60ad7b994c2126346c19769a1a5f5c8f679a05ee (patch)
tree702b5dad7b34d1ca81fd9918345f648c26d088a2 /compiler/src
parentf898f3c3a17a7c71236cafff34f507b10d71f835 (diff)
downloadcrisp-60ad7b994c2126346c19769a1a5f5c8f679a05ee.tar.gz
crisp-60ad7b994c2126346c19769a1a5f5c8f679a05ee.zip
Fix lexer processing [+-].\d as symbol instead of number
Extended lookahead in the number branch to 3 chars. Added tests for "-.5", "+.5", "-.0" in test_numbers and for "-.", "+.", ".", "+.a", "-.a" in test_ambiguous.
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/lexer/mod.rs8
-rw-r--r--compiler/src/lexer/tests.rs10
2 files changed, 15 insertions, 3 deletions
diff --git a/compiler/src/lexer/mod.rs b/compiler/src/lexer/mod.rs
index 464d88e..f3c8b76 100644
--- a/compiler/src/lexer/mod.rs
+++ b/compiler/src/lexer/mod.rs
@@ -146,8 +146,12 @@ impl<'a> Iterator for Lexer<'a> {
146 146
147 // Number 147 // Number
148 ch if ch.is_ascii_digit() 148 ch if ch.is_ascii_digit()
149 || matches!(ch, '+' | '-' | '.') 149 || ch == '.' && self.peek_nth(1).is_some_and(|ch| ch.is_ascii_digit())
150 && self.peek_nth(1).is_some_and(|ch| ch.is_ascii_digit()) => 150 || matches!(ch, '+' | '-')
151 && self.peek_nth(1).is_some_and(|ch| ch.is_ascii_digit())
152 || matches!(ch, '+' | '-')
153 && self.peek_nth(1).is_some_and(|ch| ch == '.')
154 && self.peek_nth(2).is_some_and(|ch| ch.is_ascii_digit()) =>
151 { 155 {
152 Token::Number(self.next_atom()) 156 Token::Number(self.next_atom())
153 } 157 }
diff --git a/compiler/src/lexer/tests.rs b/compiler/src/lexer/tests.rs
index 89575c7..6f96c65 100644
--- a/compiler/src/lexer/tests.rs
+++ b/compiler/src/lexer/tests.rs
@@ -1,7 +1,7 @@
1use crate::span::Pos; 1use crate::span::Pos;
2 2
3use super::Token::*; 3use super::Token::*;
4use super::*; 4use super::{Lexer, Token};
5 5
6fn tokenize<'a>(input: &'a str) -> Vec<Token<'a>> { 6fn tokenize<'a>(input: &'a str) -> Vec<Token<'a>> {
7 Lexer::new(input).map(|s| s.inner).collect() 7 Lexer::new(input).map(|s| s.inner).collect()
@@ -67,6 +67,9 @@ fn test_numbers() {
67 ("1e10", vec![Number("1e10")]), 67 ("1e10", vec![Number("1e10")]),
68 ("1.5e-3", vec![Number("1.5e-3")]), 68 ("1.5e-3", vec![Number("1.5e-3")]),
69 (".5", vec![Number(".5")]), 69 (".5", vec![Number(".5")]),
70 ("-.5", vec![Number("-.5")]),
71 ("+.5", vec![Number("+.5")]),
72 ("-.0", vec![Number("-.0")]),
70 ]; 73 ];
71 for (code, tokens) in cases { 74 for (code, tokens) in cases {
72 assert_eq!(tokenize(code), tokens); 75 assert_eq!(tokenize(code), tokens);
@@ -149,6 +152,11 @@ fn test_ambiguous() {
149 ("+foo", vec![Symbol("+foo")]), 152 ("+foo", vec![Symbol("+foo")]),
150 ("...", vec![Symbol("...")]), 153 ("...", vec![Symbol("...")]),
151 (".foo", vec![Symbol(".foo")]), 154 (".foo", vec![Symbol(".foo")]),
155 ("-.", vec![Symbol("-.")]),
156 ("+.", vec![Symbol("+.")]),
157 (".", vec![Symbol(".")]),
158 ("+.a", vec![Symbol("+.a")]),
159 ("-.a", vec![Symbol("-.a")]),
152 ]; 160 ];
153 for (code, tokens) in cases { 161 for (code, tokens) in cases {
154 assert_eq!(tokenize(code), tokens); 162 assert_eq!(tokenize(code), tokens);