mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 12:48:14 +00:00
CEL: Fix ISE.
This commit is contained in:
@@ -3,7 +3,7 @@ package cel
|
|||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
|
|
||||||
using Kind :: enum {
|
Kind :: enum {
|
||||||
Illegal,
|
Illegal,
|
||||||
EOF,
|
EOF,
|
||||||
Comment,
|
Comment,
|
||||||
@@ -95,11 +95,11 @@ Tokenizer :: struct {
|
|||||||
|
|
||||||
|
|
||||||
keywords := map[string]Kind{
|
keywords := map[string]Kind{
|
||||||
"true" = True,
|
"true" = .True,
|
||||||
"false" = False,
|
"false" = .False,
|
||||||
"nil" = Nil,
|
"nil" = .Nil,
|
||||||
"and" = And,
|
"and" = .And,
|
||||||
"or" = Or,
|
"or" = .Or,
|
||||||
};
|
};
|
||||||
|
|
||||||
kind_to_string := [len(Kind)]string{
|
kind_to_string := [len(Kind)]string{
|
||||||
@@ -138,17 +138,17 @@ kind_to_string := [len(Kind)]string{
|
|||||||
|
|
||||||
precedence :: proc(op: Kind) -> int {
|
precedence :: proc(op: Kind) -> int {
|
||||||
#partial switch op {
|
#partial switch op {
|
||||||
case Question:
|
case .Question:
|
||||||
return 1;
|
return 1;
|
||||||
case Or:
|
case .Or:
|
||||||
return 2;
|
return 2;
|
||||||
case And:
|
case .And:
|
||||||
return 3;
|
return 3;
|
||||||
case Eq, NotEq, Lt, Gt, LtEq, GtEq:
|
case .Eq, .NotEq, .Lt, .Gt, .LtEq, .GtEq:
|
||||||
return 4;
|
return 4;
|
||||||
case Add, Sub:
|
case .Add, .Sub:
|
||||||
return 5;
|
return 5;
|
||||||
case Mul, Quo, Rem:
|
case .Mul, .Quo, .Rem:
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -159,12 +159,12 @@ token_lookup :: proc(ident: string) -> Kind {
|
|||||||
if tok, is_keyword := keywords[ident]; is_keyword {
|
if tok, is_keyword := keywords[ident]; is_keyword {
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
return Ident;
|
return .Ident;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_literal :: proc(tok: Kind) -> bool { return _literal_start < tok && tok < _literal_end; }
|
is_literal :: proc(tok: Kind) -> bool { return ._literal_start < tok && tok < ._literal_end; }
|
||||||
is_operator :: proc(tok: Kind) -> bool { return _operator_start < tok && tok < _operator_end; }
|
is_operator :: proc(tok: Kind) -> bool { return ._operator_start < tok && tok < ._operator_end; }
|
||||||
is_keyword :: proc(tok: Kind) -> bool { return _keyword_start < tok && tok < _keyword_end; }
|
is_keyword :: proc(tok: Kind) -> bool { return ._keyword_start < tok && tok < ._keyword_end; }
|
||||||
|
|
||||||
|
|
||||||
tokenizer_init :: proc(t: ^Tokenizer, src: []byte, file := "") {
|
tokenizer_init :: proc(t: ^Tokenizer, src: []byte, file := "") {
|
||||||
@@ -289,7 +289,7 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (Kind, string) {
|
|||||||
scan_exponent :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (kind: Kind, text: string) {
|
scan_exponent :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (kind: Kind, text: string) {
|
||||||
kind = tok;
|
kind = tok;
|
||||||
if t.curr_rune == 'e' || t.curr_rune == 'E' {
|
if t.curr_rune == 'e' || t.curr_rune == 'E' {
|
||||||
kind = Float;
|
kind = .Float;
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
if t.curr_rune == '-' || t.curr_rune == '+' {
|
if t.curr_rune == '-' || t.curr_rune == '+' {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
@@ -306,7 +306,7 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (Kind, string) {
|
|||||||
scan_fraction :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (kind: Kind, text: string) {
|
scan_fraction :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (kind: Kind, text: string) {
|
||||||
kind = tok;
|
kind = tok;
|
||||||
if t.curr_rune == '.' {
|
if t.curr_rune == '.' {
|
||||||
kind = Float;
|
kind = .Float;
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
scan_mantissa(t, 10);
|
scan_mantissa(t, 10);
|
||||||
}
|
}
|
||||||
@@ -315,11 +315,11 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (Kind, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
offset := t.offset;
|
offset := t.offset;
|
||||||
tok := Integer;
|
tok := Kind.Integer;
|
||||||
|
|
||||||
if seen_decimal_point {
|
if seen_decimal_point {
|
||||||
offset -= 1;
|
offset -= 1;
|
||||||
tok = Float;
|
tok = .Float;
|
||||||
scan_mantissa(t, 10);
|
scan_mantissa(t, 10);
|
||||||
return scan_exponent(t, tok, offset);
|
return scan_exponent(t, tok, offset);
|
||||||
}
|
}
|
||||||
@@ -378,7 +378,7 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
case is_letter(r):
|
case is_letter(r):
|
||||||
insert_semi = true;
|
insert_semi = true;
|
||||||
lit = scan_identifier(t);
|
lit = scan_identifier(t);
|
||||||
tok = Ident;
|
tok = .Ident;
|
||||||
if len(lit) > 1 {
|
if len(lit) > 1 {
|
||||||
tok = token_lookup(lit);
|
tok = token_lookup(lit);
|
||||||
}
|
}
|
||||||
@@ -393,18 +393,18 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
case -1:
|
case -1:
|
||||||
if t.insert_semi {
|
if t.insert_semi {
|
||||||
t.insert_semi = false;
|
t.insert_semi = false;
|
||||||
return Token{Semicolon, pos, "\n"};
|
return Token{.Semicolon, pos, "\n"};
|
||||||
}
|
}
|
||||||
return Token{EOF, pos, "\n"};
|
return Token{.EOF, pos, "\n"};
|
||||||
|
|
||||||
case '\n':
|
case '\n':
|
||||||
t.insert_semi = false;
|
t.insert_semi = false;
|
||||||
return Token{Semicolon, pos, "\n"};
|
return Token{.Semicolon, pos, "\n"};
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
insert_semi = true;
|
insert_semi = true;
|
||||||
quote := r;
|
quote := r;
|
||||||
tok = String;
|
tok = .String;
|
||||||
for {
|
for {
|
||||||
this_r := t.curr_rune;
|
this_r := t.curr_rune;
|
||||||
if this_r == '\n' || r < 0 {
|
if this_r == '\n' || r < 0 {
|
||||||
@@ -430,70 +430,70 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
}
|
}
|
||||||
if t.insert_semi {
|
if t.insert_semi {
|
||||||
t.insert_semi = false;
|
t.insert_semi = false;
|
||||||
return Token{Semicolon, pos, "\n"};
|
return Token{.Semicolon, pos, "\n"};
|
||||||
}
|
}
|
||||||
// Recursive!
|
// Recursive!
|
||||||
return scan(t);
|
return scan(t);
|
||||||
|
|
||||||
case '?': tok = Question;
|
case '?': tok = .Question;
|
||||||
case ':': tok = Colon;
|
case ':': tok = .Colon;
|
||||||
case '@': tok = At;
|
case '@': tok = .At;
|
||||||
|
|
||||||
case ';':
|
case ';':
|
||||||
tok = Semicolon;
|
tok = .Semicolon;
|
||||||
lit = ";";
|
lit = ";";
|
||||||
case ',': tok = Comma;
|
case ',': tok = .Comma;
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
tok = Open_Paren;
|
tok = .Open_Paren;
|
||||||
case ')':
|
case ')':
|
||||||
insert_semi = true;
|
insert_semi = true;
|
||||||
tok = Close_Paren;
|
tok = .Close_Paren;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
tok = Open_Bracket;
|
tok = .Open_Bracket;
|
||||||
case ']':
|
case ']':
|
||||||
insert_semi = true;
|
insert_semi = true;
|
||||||
tok = Close_Bracket;
|
tok = .Close_Bracket;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
tok = Open_Brace;
|
tok = .Open_Brace;
|
||||||
case '}':
|
case '}':
|
||||||
insert_semi = true;
|
insert_semi = true;
|
||||||
tok = Close_Brace;
|
tok = .Close_Brace;
|
||||||
|
|
||||||
case '+': tok = Add;
|
case '+': tok = .Add;
|
||||||
case '-': tok = Sub;
|
case '-': tok = .Sub;
|
||||||
case '*': tok = Mul;
|
case '*': tok = .Mul;
|
||||||
case '/': tok = Quo;
|
case '/': tok = .Quo;
|
||||||
case '%': tok = Rem;
|
case '%': tok = .Rem;
|
||||||
|
|
||||||
case '!':
|
case '!':
|
||||||
tok = Not;
|
tok = .Not;
|
||||||
if t.curr_rune == '=' {
|
if t.curr_rune == '=' {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
tok = NotEq;
|
tok = .NotEq;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
tok = Assign;
|
tok = .Assign;
|
||||||
if t.curr_rune == '=' {
|
if t.curr_rune == '=' {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
tok = Eq;
|
tok = .Eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
tok = Lt;
|
tok = .Lt;
|
||||||
if t.curr_rune == '=' {
|
if t.curr_rune == '=' {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
tok = LtEq;
|
tok = .LtEq;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
tok = Gt;
|
tok = .Gt;
|
||||||
if t.curr_rune == '=' {
|
if t.curr_rune == '=' {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
tok = GtEq;
|
tok = .GtEq;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
@@ -501,7 +501,7 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
insert_semi = true;
|
insert_semi = true;
|
||||||
tok, lit = scan_number(t, true);
|
tok, lit = scan_number(t, true);
|
||||||
} else {
|
} else {
|
||||||
tok = Period;
|
tok = .Period;
|
||||||
}
|
}
|
||||||
|
|
||||||
case:
|
case:
|
||||||
@@ -509,7 +509,7 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
token_error(t, "Illegal character '%r'", r);
|
token_error(t, "Illegal character '%r'", r);
|
||||||
}
|
}
|
||||||
insert_semi = t.insert_semi;
|
insert_semi = t.insert_semi;
|
||||||
tok = Illegal;
|
tok = .Illegal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user