Support matrix type in core:odin

This commit is contained in:
gingerBill
2021-10-27 23:49:37 +01:00
parent 793a6479ef
commit 90d587df13
5 changed files with 84 additions and 20 deletions
+17
View File
@@ -224,6 +224,15 @@ Slice_Expr :: struct {
close: tokenizer.Pos,
}
Matrix_Index_Expr :: struct {
using node: Expr,
expr: ^Expr,
open: tokenizer.Pos,
row_index: ^Expr,
column_index: ^Expr,
close: tokenizer.Pos,
}
Call_Expr :: struct {
using node: Expr,
inlining: Proc_Inlining,
@@ -739,3 +748,11 @@ Relative_Type :: struct {
tag: ^Expr,
type: ^Expr,
}
Matrix_Type :: struct {
using node: Expr,
tok_pos: tokenizer.Pos,
row_count: ^Expr,
column_count: ^Expr,
elem: ^Expr,
}
+8 -1
View File
@@ -117,6 +117,10 @@ clone_node :: proc(node: ^Node) -> ^Node {
case Index_Expr:
r.expr = clone(r.expr)
r.index = clone(r.index)
case Matrix_Index_Expr:
r.expr = clone(r.expr)
r.row_index = clone(r.row_index)
r.column_index = clone(r.column_index)
case Deref_Expr:
r.expr = clone(r.expr)
case Slice_Expr:
@@ -275,7 +279,10 @@ clone_node :: proc(node: ^Node) -> ^Node {
case Map_Type:
r.key = clone(r.key)
r.value = clone(r.value)
case Matrix_Type:
r.row_count = clone(r.row_count)
r.column_count = clone(r.column_count)
r.elem = clone(r.elem)
case:
fmt.panicf("Unhandled node kind: %T", r)
}
+8
View File
@@ -110,6 +110,10 @@ walk :: proc(v: ^Visitor, node: ^Node) {
case Index_Expr:
walk(v, n.expr)
walk(v, n.index)
case Matrix_Index_Expr:
walk(v, n.expr)
walk(v, n.row_index)
walk(v, n.column_index)
case Deref_Expr:
walk(v, n.expr)
case Slice_Expr:
@@ -398,6 +402,10 @@ walk :: proc(v: ^Visitor, node: ^Node) {
case Relative_Type:
walk(v, n.tag)
walk(v, n.type)
case Matrix_Type:
walk(v, n.row_count)
walk(v, n.column_count)
walk(v, n.elem)
case:
fmt.panicf("ast.walk: unexpected node type %T", n)
+43 -13
View File
@@ -2703,6 +2703,22 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
bst.underlying = underlying
bst.close = close.pos
return bst
case .Matrix:
tok := expect_token(p, .Matrix)
expect_token(p, .Open_Bracket)
row_count := parse_expr(p, false)
expect_token(p, .Comma)
column_count := parse_expr(p, false)
expect_token(p, .Close_Bracket)
elem := parse_type(p)
mt := ast.new(ast.Matrix_Type, tok.pos, elem.end)
mt.tok_pos = tok.pos
mt.row_count = row_count
mt.column_count = column_count
mt.elem = elem
return mt
case .Asm:
tok := expect_token(p, .Asm)
@@ -2969,7 +2985,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
defer p.allow_range = prev_allow_range
p.allow_range = false
indicies: [2]^ast.Expr
indices: [2]^ast.Expr
interval: tokenizer.Token
is_slice_op := false
@@ -2981,18 +2997,18 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
// NOTE(bill): Do not err yet
break
case:
indicies[0] = parse_expr(p, false)
indices[0] = parse_expr(p, false)
}
#partial switch p.curr_tok.kind {
case .Ellipsis, .Range_Half, .Range_Full:
error(p, p.curr_tok.pos, "expected a colon, not a range")
fallthrough
case .Colon:
case .Colon, .Comma/*matrix index*/:
interval = advance_token(p)
is_slice_op = true
if p.curr_tok.kind != .Close_Bracket && p.curr_tok.kind != .EOF {
indicies[1] = parse_expr(p, false)
indices[1] = parse_expr(p, false)
}
}
@@ -3000,20 +3016,34 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
p.expr_level -= 1
if is_slice_op {
se := ast.new(ast.Slice_Expr, operand.pos, end_pos(close))
se.expr = operand
se.open = open.pos
se.low = indicies[0]
se.interval = interval
se.high = indicies[1]
se.close = close.pos
if interval.kind == .Comma {
if indices[0] == nil || indices[1] == nil {
error(p, p.curr_tok.pos, "matrix index expressions require both row and column indices")
}
se := ast.new(ast.Matrix_Index_Expr, operand.pos, end_pos(close))
se.expr = operand
se.open = open.pos
se.row_index = indices[0]
se.column_index = indices[1]
se.close = close.pos
operand = se
operand = se
} else {
se := ast.new(ast.Slice_Expr, operand.pos, end_pos(close))
se.expr = operand
se.open = open.pos
se.low = indices[0]
se.interval = interval
se.high = indices[1]
se.close = close.pos
operand = se
}
} else {
ie := ast.new(ast.Index_Expr, operand.pos, end_pos(close))
ie.expr = operand
ie.open = open.pos
ie.index = indicies[0]
ie.index = indices[0]
ie.close = close.pos
operand = ie
+8 -6
View File
@@ -150,6 +150,7 @@ Token_Kind :: enum u32 {
Asm, // asm
Inline, // inline
No_Inline, // no_inline
Matrix, // matrix
B_Keyword_End,
COUNT,
@@ -280,6 +281,7 @@ tokens := [Token_Kind.COUNT]string {
"asm",
"inline",
"no_inline",
"matrix",
"",
}
@@ -299,10 +301,10 @@ token_to_string :: proc(tok: Token) -> string {
}
to_string :: proc(kind: Token_Kind) -> string {
if Token_Kind.Invalid <= kind && kind < Token_Kind.COUNT {
if .Invalid <= kind && kind < .COUNT {
return tokens[kind]
}
if Token_Kind.B_Custom_Keyword_Begin < kind {
if .B_Custom_Keyword_Begin < kind {
n := int(u16(kind)-u16(Token_Kind.B_Custom_Keyword_Begin))
if n < len(custom_keyword_tokens) {
return custom_keyword_tokens[n]
@@ -313,7 +315,7 @@ to_string :: proc(kind: Token_Kind) -> string {
}
is_literal :: proc(kind: Token_Kind) -> bool {
return Token_Kind.B_Literal_Begin < kind && kind < Token_Kind.B_Literal_End
return .B_Literal_Begin < kind && kind < .B_Literal_End
}
is_operator :: proc(kind: Token_Kind) -> bool {
#partial switch kind {
@@ -327,13 +329,13 @@ is_operator :: proc(kind: Token_Kind) -> bool {
return false
}
is_assignment_operator :: proc(kind: Token_Kind) -> bool {
return Token_Kind.B_Assign_Op_Begin < kind && kind < Token_Kind.B_Assign_Op_End || kind == Token_Kind.Eq
return .B_Assign_Op_Begin < kind && kind < .B_Assign_Op_End || kind == .Eq
}
is_keyword :: proc(kind: Token_Kind) -> bool {
switch {
case Token_Kind.B_Keyword_Begin < kind && kind < Token_Kind.B_Keyword_End:
case .B_Keyword_Begin < kind && kind < .B_Keyword_End:
return true
case Token_Kind.B_Custom_Keyword_Begin < kind:
case .B_Custom_Keyword_Begin < kind:
return true
}
return false