|
@@ -106,11 +106,11 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
|
|
p := new(Parser);
|
|
p := new(Parser);
|
|
for {
|
|
for {
|
|
tok := scan(t);
|
|
tok := scan(t);
|
|
- if tok.kind == Kind.Illegal {
|
|
|
|
|
|
+ if tok.kind == .Illegal {
|
|
return p, false;
|
|
return p, false;
|
|
}
|
|
}
|
|
append(&p.tokens, tok);
|
|
append(&p.tokens, tok);
|
|
- if tok.kind == Kind.EOF {
|
|
|
|
|
|
+ if tok.kind == .EOF {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -120,7 +120,7 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
|
|
}
|
|
}
|
|
|
|
|
|
if len(p.tokens) == 0 {
|
|
if len(p.tokens) == 0 {
|
|
- tok := Token{kind = Kind.EOF};
|
|
|
|
|
|
+ tok := Token{kind = .EOF};
|
|
tok.line, tok.column = 1, 1;
|
|
tok.line, tok.column = 1, 1;
|
|
append(&p.tokens, tok);
|
|
append(&p.tokens, tok);
|
|
return p, true;
|
|
return p, true;
|
|
@@ -134,8 +134,8 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
|
|
p.dict_stack = make([dynamic]^Dict, 0, 4);
|
|
p.dict_stack = make([dynamic]^Dict, 0, 4);
|
|
append(&p.dict_stack, &p.root);
|
|
append(&p.dict_stack, &p.root);
|
|
|
|
|
|
- for p.curr_token.kind != Kind.EOF &&
|
|
|
|
- p.curr_token.kind != Kind.Illegal &&
|
|
|
|
|
|
+ for p.curr_token.kind != .EOF &&
|
|
|
|
+ p.curr_token.kind != .Illegal &&
|
|
p.curr_token_index < len(p.tokens) {
|
|
p.curr_token_index < len(p.tokens) {
|
|
if !parse_assignment(p) {
|
|
if !parse_assignment(p) {
|
|
break;
|
|
break;
|
|
@@ -147,7 +147,7 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
|
|
|
|
|
|
destroy :: proc(p: ^Parser) {
|
|
destroy :: proc(p: ^Parser) {
|
|
destroy_value :: proc(value: Value) {
|
|
destroy_value :: proc(value: Value) {
|
|
- switch v in value {
|
|
|
|
|
|
+ #partial switch v in value {
|
|
case Array:
|
|
case Array:
|
|
for elem in v do destroy_value(elem);
|
|
for elem in v do destroy_value(elem);
|
|
delete(v);
|
|
delete(v);
|
|
@@ -287,7 +287,7 @@ unquote_char :: proc(str: string, quote: byte) -> (r: rune, multiple_bytes: bool
|
|
|
|
|
|
|
|
|
|
unquote_string :: proc(p: ^Parser, t: Token) -> (string, bool) {
|
|
unquote_string :: proc(p: ^Parser, t: Token) -> (string, bool) {
|
|
- if t.kind != Kind.String {
|
|
|
|
|
|
+ if t.kind != .String {
|
|
return t.lit, true;
|
|
return t.lit, true;
|
|
}
|
|
}
|
|
s := t.lit;
|
|
s := t.lit;
|
|
@@ -368,8 +368,8 @@ expect_operator :: proc(p: ^Parser) -> Token {
|
|
|
|
|
|
fix_advance :: proc(p: ^Parser) {
|
|
fix_advance :: proc(p: ^Parser) {
|
|
for {
|
|
for {
|
|
- switch t := p.curr_token; t.kind {
|
|
|
|
- case Kind.EOF, Kind.Semicolon:
|
|
|
|
|
|
+ #partial switch t := p.curr_token; t.kind {
|
|
|
|
+ case .EOF, .Semicolon:
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
next_token(p);
|
|
next_token(p);
|
|
@@ -377,7 +377,7 @@ fix_advance :: proc(p: ^Parser) {
|
|
}
|
|
}
|
|
|
|
|
|
copy_value :: proc(value: Value) -> Value {
|
|
copy_value :: proc(value: Value) -> Value {
|
|
- switch v in value {
|
|
|
|
|
|
+ #partial switch v in value {
|
|
case Array:
|
|
case Array:
|
|
a := make(Array, len(v));
|
|
a := make(Array, len(v));
|
|
for elem, idx in v {
|
|
for elem, idx in v {
|
|
@@ -407,79 +407,79 @@ lookup_value :: proc(p: ^Parser, name: string) -> (Value, bool) {
|
|
|
|
|
|
parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
|
parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
|
tok := p.curr_token;
|
|
tok := p.curr_token;
|
|
- switch p.curr_token.kind {
|
|
|
|
- case Kind.Ident:
|
|
|
|
|
|
+ #partial switch p.curr_token.kind {
|
|
|
|
+ case .Ident:
|
|
next_token(p);
|
|
next_token(p);
|
|
v, ok := lookup_value(p, tok.lit);
|
|
v, ok := lookup_value(p, tok.lit);
|
|
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
|
|
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
|
|
return v, tok.pos;
|
|
return v, tok.pos;
|
|
|
|
|
|
- case Kind.True:
|
|
|
|
|
|
+ case .True:
|
|
next_token(p);
|
|
next_token(p);
|
|
return true, tok.pos;
|
|
return true, tok.pos;
|
|
- case Kind.False:
|
|
|
|
|
|
+ case .False:
|
|
next_token(p);
|
|
next_token(p);
|
|
return false, tok.pos;
|
|
return false, tok.pos;
|
|
|
|
|
|
- case Kind.Nil:
|
|
|
|
|
|
+ case .Nil:
|
|
next_token(p);
|
|
next_token(p);
|
|
return Nil_Value{}, tok.pos;
|
|
return Nil_Value{}, tok.pos;
|
|
|
|
|
|
- case Kind.Integer:
|
|
|
|
|
|
+ case .Integer:
|
|
next_token(p);
|
|
next_token(p);
|
|
return strconv.parse_i64(tok.lit), tok.pos;
|
|
return strconv.parse_i64(tok.lit), tok.pos;
|
|
|
|
|
|
- case Kind.Float:
|
|
|
|
|
|
+ case .Float:
|
|
next_token(p);
|
|
next_token(p);
|
|
return strconv.parse_f64(tok.lit), tok.pos;
|
|
return strconv.parse_f64(tok.lit), tok.pos;
|
|
|
|
|
|
- case Kind.String:
|
|
|
|
|
|
+ case .String:
|
|
next_token(p);
|
|
next_token(p);
|
|
str, ok := unquote_string(p, tok);
|
|
str, ok := unquote_string(p, tok);
|
|
if !ok do error(p, tok.pos, "Unable to unquote string");
|
|
if !ok do error(p, tok.pos, "Unable to unquote string");
|
|
return string(str), tok.pos;
|
|
return string(str), tok.pos;
|
|
|
|
|
|
- case Kind.Open_Paren:
|
|
|
|
- expect_token(p, Kind.Open_Paren);
|
|
|
|
|
|
+ case .Open_Paren:
|
|
|
|
+ expect_token(p, .Open_Paren);
|
|
expr, _ := parse_expr(p);
|
|
expr, _ := parse_expr(p);
|
|
- expect_token(p, Kind.Close_Paren);
|
|
|
|
|
|
+ expect_token(p, .Close_Paren);
|
|
return expr, tok.pos;
|
|
return expr, tok.pos;
|
|
|
|
|
|
- case Kind.Open_Bracket:
|
|
|
|
- expect_token(p, Kind.Open_Bracket);
|
|
|
|
|
|
+ case .Open_Bracket:
|
|
|
|
+ expect_token(p, .Open_Bracket);
|
|
elems := make([dynamic]Value, 0, 4);
|
|
elems := make([dynamic]Value, 0, 4);
|
|
- for p.curr_token.kind != Kind.Close_Bracket &&
|
|
|
|
- p.curr_token.kind != Kind.EOF {
|
|
|
|
|
|
+ for p.curr_token.kind != .Close_Bracket &&
|
|
|
|
+ p.curr_token.kind != .EOF {
|
|
elem, _ := parse_expr(p);
|
|
elem, _ := parse_expr(p);
|
|
append(&elems, elem);
|
|
append(&elems, elem);
|
|
|
|
|
|
- if p.curr_token.kind == Kind.Semicolon && p.curr_token.lit == "\n" {
|
|
|
|
|
|
+ if p.curr_token.kind == .Semicolon && p.curr_token.lit == "\n" {
|
|
next_token(p);
|
|
next_token(p);
|
|
- } else if !allow_token(p, Kind.Comma) {
|
|
|
|
|
|
+ } else if !allow_token(p, .Comma) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
- expect_token(p, Kind.Close_Bracket);
|
|
|
|
|
|
+ expect_token(p, .Close_Bracket);
|
|
return Array(elems[:]), tok.pos;
|
|
return Array(elems[:]), tok.pos;
|
|
|
|
|
|
- case Kind.Open_Brace:
|
|
|
|
- expect_token(p, Kind.Open_Brace);
|
|
|
|
|
|
+ case .Open_Brace:
|
|
|
|
+ expect_token(p, .Open_Brace);
|
|
|
|
|
|
dict := Dict{};
|
|
dict := Dict{};
|
|
append(&p.dict_stack, &dict);
|
|
append(&p.dict_stack, &dict);
|
|
defer pop(&p.dict_stack);
|
|
defer pop(&p.dict_stack);
|
|
|
|
|
|
- for p.curr_token.kind != Kind.Close_Brace &&
|
|
|
|
- p.curr_token.kind != Kind.EOF {
|
|
|
|
|
|
+ for p.curr_token.kind != .Close_Brace &&
|
|
|
|
+ p.curr_token.kind != .EOF {
|
|
name_tok := p.curr_token;
|
|
name_tok := p.curr_token;
|
|
- if !allow_token(p, Kind.Ident) && !allow_token(p, Kind.String) {
|
|
|
|
- name_tok = expect_token(p, Kind.Ident);
|
|
|
|
|
|
+ if !allow_token(p, .Ident) && !allow_token(p, .String) {
|
|
|
|
+ name_tok = expect_token(p, .Ident);
|
|
}
|
|
}
|
|
|
|
|
|
name, ok := unquote_string(p, name_tok);
|
|
name, ok := unquote_string(p, name_tok);
|
|
if !ok do error(p, tok.pos, "Unable to unquote string");
|
|
if !ok do error(p, tok.pos, "Unable to unquote string");
|
|
- expect_token(p, Kind.Assign);
|
|
|
|
|
|
+ expect_token(p, .Assign);
|
|
elem, _ := parse_expr(p);
|
|
elem, _ := parse_expr(p);
|
|
|
|
|
|
if _, ok2 := dict[name]; ok2 {
|
|
if _, ok2 := dict[name]; ok2 {
|
|
@@ -488,13 +488,13 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
|
dict[name] = elem;
|
|
dict[name] = elem;
|
|
}
|
|
}
|
|
|
|
|
|
- if p.curr_token.kind == Kind.Semicolon && p.curr_token.lit == "\n" {
|
|
|
|
|
|
+ if p.curr_token.kind == .Semicolon && p.curr_token.lit == "\n" {
|
|
next_token(p);
|
|
next_token(p);
|
|
- } else if !allow_token(p, Kind.Comma) {
|
|
|
|
|
|
+ } else if !allow_token(p, .Comma) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- expect_token(p, Kind.Close_Brace);
|
|
|
|
|
|
+ expect_token(p, .Close_Brace);
|
|
return dict, tok.pos;
|
|
return dict, tok.pos;
|
|
|
|
|
|
}
|
|
}
|
|
@@ -504,13 +504,13 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
|
parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
|
parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
|
loop := true;
|
|
loop := true;
|
|
for operand := operand; loop; {
|
|
for operand := operand; loop; {
|
|
- switch p.curr_token.kind {
|
|
|
|
- case Kind.Period:
|
|
|
|
|
|
+ #partial switch p.curr_token.kind {
|
|
|
|
+ case .Period:
|
|
next_token(p);
|
|
next_token(p);
|
|
tok := next_token(p);
|
|
tok := next_token(p);
|
|
|
|
|
|
- switch tok.kind {
|
|
|
|
- case Kind.Ident:
|
|
|
|
|
|
+ #partial switch tok.kind {
|
|
|
|
+ case .Ident:
|
|
d, ok := operand.(Dict);
|
|
d, ok := operand.(Dict);
|
|
if !ok || d == nil {
|
|
if !ok || d == nil {
|
|
error(p, tok.pos, "Expected a dictionary");
|
|
error(p, tok.pos, "Expected a dictionary");
|
|
@@ -531,13 +531,13 @@ parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
|
operand = nil;
|
|
operand = nil;
|
|
}
|
|
}
|
|
|
|
|
|
- case Kind.Open_Bracket:
|
|
|
|
- expect_token(p, Kind.Open_Bracket);
|
|
|
|
|
|
+ case .Open_Bracket:
|
|
|
|
+ expect_token(p, .Open_Bracket);
|
|
index, index_pos := parse_expr(p);
|
|
index, index_pos := parse_expr(p);
|
|
- expect_token(p, Kind.Close_Bracket);
|
|
|
|
|
|
+ expect_token(p, .Close_Bracket);
|
|
|
|
|
|
|
|
|
|
- switch a in operand {
|
|
|
|
|
|
+ #partial switch a in operand {
|
|
case Array:
|
|
case Array:
|
|
i, ok := index.(i64);
|
|
i, ok := index.(i64);
|
|
if !ok {
|
|
if !ok {
|
|
@@ -587,22 +587,22 @@ parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
|
|
|
|
|
parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
|
parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
|
op := p.curr_token;
|
|
op := p.curr_token;
|
|
- switch p.curr_token.kind {
|
|
|
|
- case Kind.At:
|
|
|
|
|
|
+ #partial switch p.curr_token.kind {
|
|
|
|
+ case .At:
|
|
next_token(p);
|
|
next_token(p);
|
|
- tok := expect_token(p, Kind.String);
|
|
|
|
|
|
+ tok := expect_token(p, .String);
|
|
v, ok := lookup_value(p, tok.lit);
|
|
v, ok := lookup_value(p, tok.lit);
|
|
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
|
|
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
|
|
return parse_atom_expr(p, v, tok.pos);
|
|
return parse_atom_expr(p, v, tok.pos);
|
|
|
|
|
|
- case Kind.Add, Kind.Sub:
|
|
|
|
|
|
+ case .Add, .Sub:
|
|
next_token(p);
|
|
next_token(p);
|
|
// TODO(bill): Calcuate values as you go!
|
|
// TODO(bill): Calcuate values as you go!
|
|
expr, pos := parse_unary_expr(p);
|
|
expr, pos := parse_unary_expr(p);
|
|
|
|
|
|
- switch e in expr {
|
|
|
|
- case i64: if op.kind == Kind.Sub do return -e, pos;
|
|
|
|
- case f64: if op.kind == Kind.Sub do return -e, pos;
|
|
|
|
|
|
+ #partial switch e in expr {
|
|
|
|
+ case i64: if op.kind == .Sub do return -e, pos;
|
|
|
|
+ case f64: if op.kind == .Sub do return -e, pos;
|
|
case:
|
|
case:
|
|
error(p, op.pos, "Unary operator %s can only be used on integers or floats", op.lit);
|
|
error(p, op.pos, "Unary operator %s can only be used on integers or floats", op.lit);
|
|
return nil, op.pos;
|
|
return nil, op.pos;
|
|
@@ -610,7 +610,7 @@ parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
|
|
|
|
|
return expr, op.pos;
|
|
return expr, op.pos;
|
|
|
|
|
|
- case Kind.Not:
|
|
|
|
|
|
+ case .Not:
|
|
next_token(p);
|
|
next_token(p);
|
|
expr, _ := parse_unary_expr(p);
|
|
expr, _ := parse_unary_expr(p);
|
|
if v, ok := expr.(bool); ok {
|
|
if v, ok := expr.(bool); ok {
|
|
@@ -625,7 +625,7 @@ parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
|
|
|
|
|
|
|
|
|
value_order :: proc(v: Value) -> int {
|
|
value_order :: proc(v: Value) -> int {
|
|
- switch _ in v {
|
|
|
|
|
|
+ #partial switch _ in v {
|
|
case bool, string:
|
|
case bool, string:
|
|
return 1;
|
|
return 1;
|
|
case i64:
|
|
case i64:
|
|
@@ -641,13 +641,13 @@ match_values :: proc(left, right: ^Value) -> bool {
|
|
return match_values(right, left);
|
|
return match_values(right, left);
|
|
}
|
|
}
|
|
|
|
|
|
- switch x in left^ {
|
|
|
|
|
|
+ #partial switch x in left^ {
|
|
case:
|
|
case:
|
|
right^ = left^;
|
|
right^ = left^;
|
|
case bool, string:
|
|
case bool, string:
|
|
return true;
|
|
return true;
|
|
case i64:
|
|
case i64:
|
|
- switch y in right^ {
|
|
|
|
|
|
+ #partial switch y in right^ {
|
|
case i64:
|
|
case i64:
|
|
return true;
|
|
return true;
|
|
case f64:
|
|
case f64:
|
|
@@ -656,7 +656,7 @@ match_values :: proc(left, right: ^Value) -> bool {
|
|
}
|
|
}
|
|
|
|
|
|
case f64:
|
|
case f64:
|
|
- switch y in right {
|
|
|
|
|
|
+ #partial switch y in right {
|
|
case f64:
|
|
case f64:
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -671,59 +671,59 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
|
|
match_values(&x, &y);
|
|
match_values(&x, &y);
|
|
|
|
|
|
|
|
|
|
- switch a in x {
|
|
|
|
|
|
+ #partial switch a in x {
|
|
case: return x, true;
|
|
case: return x, true;
|
|
|
|
|
|
case bool:
|
|
case bool:
|
|
b, ok := y.(bool);
|
|
b, ok := y.(bool);
|
|
if !ok do return nil, false;
|
|
if !ok do return nil, false;
|
|
- switch op {
|
|
|
|
- case Kind.Eq: return a == b, true;
|
|
|
|
- case Kind.NotEq: return a != b, true;
|
|
|
|
- case Kind.And: return a && b, true;
|
|
|
|
- case Kind.Or: return a || b, true;
|
|
|
|
|
|
+ #partial switch op {
|
|
|
|
+ case .Eq: return a == b, true;
|
|
|
|
+ case .NotEq: return a != b, true;
|
|
|
|
+ case .And: return a && b, true;
|
|
|
|
+ case .Or: return a || b, true;
|
|
}
|
|
}
|
|
|
|
|
|
case i64:
|
|
case i64:
|
|
b, ok := y.(i64);
|
|
b, ok := y.(i64);
|
|
if !ok do return nil, false;
|
|
if !ok do return nil, false;
|
|
- switch op {
|
|
|
|
- case Kind.Add: return a + b, true;
|
|
|
|
- case Kind.Sub: return a - b, true;
|
|
|
|
- case Kind.Mul: return a * b, true;
|
|
|
|
- case Kind.Quo: return a / b, true;
|
|
|
|
- case Kind.Rem: return a % b, true;
|
|
|
|
- case Kind.Eq: return a == b, true;
|
|
|
|
- case Kind.NotEq: return a != b, true;
|
|
|
|
- case Kind.Lt: return a < b, true;
|
|
|
|
- case Kind.Gt: return a > b, true;
|
|
|
|
- case Kind.LtEq: return a <= b, true;
|
|
|
|
- case Kind.GtEq: return a >= b, true;
|
|
|
|
|
|
+ #partial switch op {
|
|
|
|
+ case .Add: return a + b, true;
|
|
|
|
+ case .Sub: return a - b, true;
|
|
|
|
+ case .Mul: return a * b, true;
|
|
|
|
+ case .Quo: return a / b, true;
|
|
|
|
+ case .Rem: return a % b, true;
|
|
|
|
+ case .Eq: return a == b, true;
|
|
|
|
+ case .NotEq: return a != b, true;
|
|
|
|
+ case .Lt: return a < b, true;
|
|
|
|
+ case .Gt: return a > b, true;
|
|
|
|
+ case .LtEq: return a <= b, true;
|
|
|
|
+ case .GtEq: return a >= b, true;
|
|
}
|
|
}
|
|
|
|
|
|
case f64:
|
|
case f64:
|
|
b, ok := y.(f64);
|
|
b, ok := y.(f64);
|
|
if !ok do return nil, false;
|
|
if !ok do return nil, false;
|
|
|
|
|
|
- switch op {
|
|
|
|
- case Kind.Add: return a + b, true;
|
|
|
|
- case Kind.Sub: return a - b, true;
|
|
|
|
- case Kind.Mul: return a * b, true;
|
|
|
|
- case Kind.Quo: return a / b, true;
|
|
|
|
- case Kind.Eq: return a == b, true;
|
|
|
|
- case Kind.NotEq: return a != b, true;
|
|
|
|
- case Kind.Lt: return a < b, true;
|
|
|
|
- case Kind.Gt: return a > b, true;
|
|
|
|
- case Kind.LtEq: return a <= b, true;
|
|
|
|
- case Kind.GtEq: return a >= b, true;
|
|
|
|
|
|
+ #partial switch op {
|
|
|
|
+ case .Add: return a + b, true;
|
|
|
|
+ case .Sub: return a - b, true;
|
|
|
|
+ case .Mul: return a * b, true;
|
|
|
|
+ case .Quo: return a / b, true;
|
|
|
|
+ case .Eq: return a == b, true;
|
|
|
|
+ case .NotEq: return a != b, true;
|
|
|
|
+ case .Lt: return a < b, true;
|
|
|
|
+ case .Gt: return a > b, true;
|
|
|
|
+ case .LtEq: return a <= b, true;
|
|
|
|
+ case .GtEq: return a >= b, true;
|
|
}
|
|
}
|
|
|
|
|
|
case string:
|
|
case string:
|
|
b, ok := y.(string);
|
|
b, ok := y.(string);
|
|
if !ok do return nil, false;
|
|
if !ok do return nil, false;
|
|
|
|
|
|
- switch op {
|
|
|
|
- case Kind.Add:
|
|
|
|
|
|
+ #partial switch op {
|
|
|
|
+ case .Add:
|
|
n := len(a) + len(b);
|
|
n := len(a) + len(b);
|
|
data := make([]byte, n);
|
|
data := make([]byte, n);
|
|
copy(data[:], a);
|
|
copy(data[:], a);
|
|
@@ -732,12 +732,12 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
|
|
append(&p.allocated_strings, s);
|
|
append(&p.allocated_strings, s);
|
|
return s, true;
|
|
return s, true;
|
|
|
|
|
|
- case Kind.Eq: return a == b, true;
|
|
|
|
- case Kind.NotEq: return a != b, true;
|
|
|
|
- case Kind.Lt: return a < b, true;
|
|
|
|
- case Kind.Gt: return a > b, true;
|
|
|
|
- case Kind.LtEq: return a <= b, true;
|
|
|
|
- case Kind.GtEq: return a >= b, true;
|
|
|
|
|
|
+ case .Eq: return a == b, true;
|
|
|
|
+ case .NotEq: return a != b, true;
|
|
|
|
+ case .Lt: return a < b, true;
|
|
|
|
+ case .Gt: return a > b, true;
|
|
|
|
+ case .LtEq: return a <= b, true;
|
|
|
|
+ case .GtEq: return a >= b, true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -755,10 +755,10 @@ parse_binary_expr :: proc(p: ^Parser, prec_in: int) -> (Value, Pos) {
|
|
}
|
|
}
|
|
expect_operator(p);
|
|
expect_operator(p);
|
|
|
|
|
|
- if op.kind == Kind.Question {
|
|
|
|
|
|
+ if op.kind == .Question {
|
|
cond := expr;
|
|
cond := expr;
|
|
x, _ := parse_expr(p);
|
|
x, _ := parse_expr(p);
|
|
- expect_token(p, Kind.Colon);
|
|
|
|
|
|
+ expect_token(p, .Colon);
|
|
y, _ := parse_expr(p);
|
|
y, _ := parse_expr(p);
|
|
|
|
|
|
if t, ok := cond.(bool); ok {
|
|
if t, ok := cond.(bool); ok {
|
|
@@ -791,13 +791,13 @@ parse_expr :: proc(p: ^Parser) -> (Value, Pos) {
|
|
expect_semicolon :: proc(p: ^Parser) {
|
|
expect_semicolon :: proc(p: ^Parser) {
|
|
kind := p.curr_token.kind;
|
|
kind := p.curr_token.kind;
|
|
|
|
|
|
- switch kind {
|
|
|
|
- case Kind.Comma:
|
|
|
|
|
|
+ #partial switch kind {
|
|
|
|
+ case .Comma:
|
|
error(p, p.curr_token.pos, "Expected ';', got ','");
|
|
error(p, p.curr_token.pos, "Expected ';', got ','");
|
|
next_token(p);
|
|
next_token(p);
|
|
- case Kind.Semicolon:
|
|
|
|
|
|
+ case .Semicolon:
|
|
next_token(p);
|
|
next_token(p);
|
|
- case Kind.EOF:
|
|
|
|
|
|
+ case .EOF:
|
|
// okay
|
|
// okay
|
|
case:
|
|
case:
|
|
error(p, p.curr_token.pos, "Expected ';', got %s", p.curr_token.lit);
|
|
error(p, p.curr_token.pos, "Expected ';', got %s", p.curr_token.lit);
|
|
@@ -811,17 +811,17 @@ parse_assignment :: proc(p: ^Parser) -> bool {
|
|
return p.dict_stack[len(p.dict_stack)-1];
|
|
return p.dict_stack[len(p.dict_stack)-1];
|
|
}
|
|
}
|
|
|
|
|
|
- if p.curr_token.kind == Kind.Semicolon {
|
|
|
|
|
|
+ if p.curr_token.kind == .Semicolon {
|
|
next_token(p);
|
|
next_token(p);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- if p.curr_token.kind == Kind.EOF {
|
|
|
|
|
|
+ if p.curr_token.kind == .EOF {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
tok := p.curr_token;
|
|
tok := p.curr_token;
|
|
- if allow_token(p, Kind.Ident) || allow_token(p, Kind.String) {
|
|
|
|
- expect_token(p, Kind.Assign);
|
|
|
|
|
|
+ if allow_token(p, .Ident) || allow_token(p, .String) {
|
|
|
|
+ expect_token(p, .Assign);
|
|
name, ok := unquote_string(p, tok);
|
|
name, ok := unquote_string(p, tok);
|
|
if !ok do error(p, tok.pos, "Unable to unquote string");
|
|
if !ok do error(p, tok.pos, "Unable to unquote string");
|
|
expr, _ := parse_expr(p);
|
|
expr, _ := parse_expr(p);
|