aboutsummaryrefslogtreecommitdiff
path: root/core/encoding
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-12-22 12:03:48 +0000
committergingerBill <bill@gingerbill.org>2019-12-22 12:03:48 +0000
commitd1c9fd4e012e16cee73e9ef0af716caf34430d81 (patch)
tree048a9dd6ed2294d685761e31081620a924ee6ef9 /core/encoding
parent45937306321df28266c793b7225eb10ad3d741e2 (diff)
Implement `#complete switch` by default, replace with `#partial switch` #511
Diffstat (limited to 'core/encoding')
-rw-r--r--core/encoding/cel/cel.odin210
-rw-r--r--core/encoding/cel/token.odin2
-rw-r--r--core/encoding/json/marshal.odin4
-rw-r--r--core/encoding/json/parser.odin4
-rw-r--r--core/encoding/json/types.odin2
-rw-r--r--core/encoding/json/validator.odin17
6 files changed, 119 insertions, 120 deletions
diff --git a/core/encoding/cel/cel.odin b/core/encoding/cel/cel.odin
index fe36978c2..ead61c05e 100644
--- a/core/encoding/cel/cel.odin
+++ b/core/encoding/cel/cel.odin
@@ -106,11 +106,11 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
p := new(Parser);
for {
tok := scan(t);
- if tok.kind == Kind.Illegal {
+ if tok.kind == .Illegal {
return p, false;
}
append(&p.tokens, tok);
- if tok.kind == Kind.EOF {
+ if tok.kind == .EOF {
break;
}
}
@@ -120,7 +120,7 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
}
if len(p.tokens) == 0 {
- tok := Token{kind = Kind.EOF};
+ tok := Token{kind = .EOF};
tok.line, tok.column = 1, 1;
append(&p.tokens, tok);
return p, true;
@@ -134,8 +134,8 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
p.dict_stack = make([dynamic]^Dict, 0, 4);
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) {
if !parse_assignment(p) {
break;
@@ -147,7 +147,7 @@ create_from_tokenizer :: proc(t: ^Tokenizer) -> (^Parser, bool) {
destroy :: proc(p: ^Parser) {
destroy_value :: proc(value: Value) {
- switch v in value {
+ #partial switch v in value {
case Array:
for elem in v do destroy_value(elem);
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) {
- if t.kind != Kind.String {
+ if t.kind != .String {
return t.lit, true;
}
s := t.lit;
@@ -368,8 +368,8 @@ expect_operator :: proc(p: ^Parser) -> Token {
fix_advance :: proc(p: ^Parser) {
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;
}
next_token(p);
@@ -377,7 +377,7 @@ fix_advance :: proc(p: ^Parser) {
}
copy_value :: proc(value: Value) -> Value {
- switch v in value {
+ #partial switch v in value {
case Array:
a := make(Array, len(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) {
tok := p.curr_token;
- switch p.curr_token.kind {
- case Kind.Ident:
+ #partial switch p.curr_token.kind {
+ case .Ident:
next_token(p);
v, ok := lookup_value(p, tok.lit);
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
return v, tok.pos;
- case Kind.True:
+ case .True:
next_token(p);
return true, tok.pos;
- case Kind.False:
+ case .False:
next_token(p);
return false, tok.pos;
- case Kind.Nil:
+ case .Nil:
next_token(p);
return Nil_Value{}, tok.pos;
- case Kind.Integer:
+ case .Integer:
next_token(p);
return strconv.parse_i64(tok.lit), tok.pos;
- case Kind.Float:
+ case .Float:
next_token(p);
return strconv.parse_f64(tok.lit), tok.pos;
- case Kind.String:
+ case .String:
next_token(p);
str, ok := unquote_string(p, tok);
if !ok do error(p, tok.pos, "Unable to unquote string");
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);
- expect_token(p, Kind.Close_Paren);
+ expect_token(p, .Close_Paren);
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);
- 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);
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);
- } else if !allow_token(p, Kind.Comma) {
+ } else if !allow_token(p, .Comma) {
break;
}
}
- expect_token(p, Kind.Close_Bracket);
+ expect_token(p, .Close_Bracket);
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{};
append(&p.dict_stack, &dict);
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;
- 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);
if !ok do error(p, tok.pos, "Unable to unquote string");
- expect_token(p, Kind.Assign);
+ expect_token(p, .Assign);
elem, _ := parse_expr(p);
if _, ok2 := dict[name]; ok2 {
@@ -488,13 +488,13 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
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);
- } else if !allow_token(p, Kind.Comma) {
+ } else if !allow_token(p, .Comma) {
break;
}
}
- expect_token(p, Kind.Close_Brace);
+ expect_token(p, .Close_Brace);
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) {
loop := true;
for operand := operand; loop; {
- switch p.curr_token.kind {
- case Kind.Period:
+ #partial switch p.curr_token.kind {
+ case .Period:
next_token(p);
tok := next_token(p);
- switch tok.kind {
- case Kind.Ident:
+ #partial switch tok.kind {
+ case .Ident:
d, ok := operand.(Dict);
if !ok || d == nil {
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;
}
- case Kind.Open_Bracket:
- expect_token(p, Kind.Open_Bracket);
+ case .Open_Bracket:
+ expect_token(p, .Open_Bracket);
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:
i, ok := index.(i64);
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) {
op := p.curr_token;
- switch p.curr_token.kind {
- case Kind.At:
+ #partial switch p.curr_token.kind {
+ case .At:
next_token(p);
- tok := expect_token(p, Kind.String);
+ tok := expect_token(p, .String);
v, ok := lookup_value(p, tok.lit);
if !ok do error(p, tok.pos, "Undeclared identifier %s", tok.lit);
return parse_atom_expr(p, v, tok.pos);
- case Kind.Add, Kind.Sub:
+ case .Add, .Sub:
next_token(p);
// TODO(bill): Calcuate values as you go!
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:
error(p, op.pos, "Unary operator %s can only be used on integers or floats", op.lit);
return nil, op.pos;
@@ -610,7 +610,7 @@ parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
return expr, op.pos;
- case Kind.Not:
+ case .Not:
next_token(p);
expr, _ := parse_unary_expr(p);
if v, ok := expr.(bool); ok {
@@ -625,7 +625,7 @@ parse_unary_expr :: proc(p: ^Parser) -> (Value, Pos) {
value_order :: proc(v: Value) -> int {
- switch _ in v {
+ #partial switch _ in v {
case bool, string:
return 1;
case i64:
@@ -641,13 +641,13 @@ match_values :: proc(left, right: ^Value) -> bool {
return match_values(right, left);
}
- switch x in left^ {
+ #partial switch x in left^ {
case:
right^ = left^;
case bool, string:
return true;
case i64:
- switch y in right^ {
+ #partial switch y in right^ {
case i64:
return true;
case f64:
@@ -656,7 +656,7 @@ match_values :: proc(left, right: ^Value) -> bool {
}
case f64:
- switch y in right {
+ #partial switch y in right {
case f64:
return true;
}
@@ -671,59 +671,59 @@ calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, boo
match_values(&x, &y);
- switch a in x {
+ #partial switch a in x {
case: return x, true;
case bool:
b, ok := y.(bool);
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:
b, ok := y.(i64);
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:
b, ok := y.(f64);
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:
b, ok := y.(string);
if !ok do return nil, false;
- switch op {
- case Kind.Add:
+ #partial switch op {
+ case .Add:
n := len(a) + len(b);
data := make([]byte, n);
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);
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);
- if op.kind == Kind.Question {
+ if op.kind == .Question {
cond := expr;
x, _ := parse_expr(p);
- expect_token(p, Kind.Colon);
+ expect_token(p, .Colon);
y, _ := parse_expr(p);
if t, ok := cond.(bool); ok {
@@ -791,13 +791,13 @@ parse_expr :: proc(p: ^Parser) -> (Value, Pos) {
expect_semicolon :: proc(p: ^Parser) {
kind := p.curr_token.kind;
- switch kind {
- case Kind.Comma:
+ #partial switch kind {
+ case .Comma:
error(p, p.curr_token.pos, "Expected ';', got ','");
next_token(p);
- case Kind.Semicolon:
+ case .Semicolon:
next_token(p);
- case Kind.EOF:
+ case .EOF:
// okay
case:
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];
}
- if p.curr_token.kind == Kind.Semicolon {
+ if p.curr_token.kind == .Semicolon {
next_token(p);
return true;
}
- if p.curr_token.kind == Kind.EOF {
+ if p.curr_token.kind == .EOF {
return false;
}
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);
if !ok do error(p, tok.pos, "Unable to unquote string");
expr, _ := parse_expr(p);
diff --git a/core/encoding/cel/token.odin b/core/encoding/cel/token.odin
index a2bcb963a..6d6238014 100644
--- a/core/encoding/cel/token.odin
+++ b/core/encoding/cel/token.odin
@@ -137,7 +137,7 @@ kind_to_string := [len(Kind)]string{
};
precedence :: proc(op: Kind) -> int {
- switch op {
+ #partial switch op {
case Question:
return 1;
case Or:
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin
index f3d894f3f..4e4447143 100644
--- a/core/encoding/json/marshal.odin
+++ b/core/encoding/json/marshal.odin
@@ -40,7 +40,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
ti := type_info_base(type_info_of(v.id));
a := any{v.data, ti.id};
- switch info in ti.variant {
+ #partial switch info in ti.variant {
case Type_Info_Named:
panic("Unreachable");
@@ -282,7 +282,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
return false;
}
t := runtime.type_info_base(ti);
- switch info in t.variant {
+ #partial switch info in t.variant {
case runtime.Type_Info_Integer:
switch info.endianness {
case .Platform: return false;
diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin
index 36a68f31c..8503edd98 100644
--- a/core/encoding/json/parser.odin
+++ b/core/encoding/json/parser.odin
@@ -70,7 +70,7 @@ parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
defer value.end = token_end_pos(p.prev_token);
token := p.curr_token;
- switch token.kind {
+ #partial switch token.kind {
case Kind.Null:
value.value = Null{};
advance_token(p);
@@ -105,7 +105,7 @@ parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
case:
if p.spec == Specification.JSON5 {
- switch token.kind {
+ #partial switch token.kind {
case Kind.Infinity:
inf: u64 = 0x7ff0000000000000;
if token.text[0] == '-' {
diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin
index 036fe50b4..1c106d591 100644
--- a/core/encoding/json/types.odin
+++ b/core/encoding/json/types.odin
@@ -56,7 +56,7 @@ Error :: enum {
destroy_value :: proc(value: Value) {
- switch v in value.value {
+ #partial switch v in value.value {
case Object:
for key, elem in v {
delete(key);
diff --git a/core/encoding/json/validator.odin b/core/encoding/json/validator.odin
index 17073f102..77339bbc3 100644
--- a/core/encoding/json/validator.odin
+++ b/core/encoding/json/validator.odin
@@ -91,28 +91,27 @@ validate_array :: proc(p: ^Parser) -> bool {
validate_value :: proc(p: ^Parser) -> bool {
token := p.curr_token;
- using Kind;
- switch token.kind {
- case Null, False, True:
+ #partial switch token.kind {
+ case .Null, .False, .True:
advance_token(p);
return true;
- case Integer, Float:
+ case .Integer, .Float:
advance_token(p);
return true;
- case String:
+ case .String:
advance_token(p);
return is_valid_string_literal(token.text, p.spec);
- case Open_Brace:
+ case .Open_Brace:
return validate_object(p);
- case Open_Bracket:
+ case .Open_Bracket:
return validate_array(p);
case:
if p.spec == Specification.JSON5 {
- switch token.kind {
- case Infinity, NaN:
+ #partial switch token.kind {
+ case .Infinity, .NaN:
advance_token(p);
return true;
}