mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-21 21:24:59 -07:00
Support matrix type in core:odin
This commit is contained in:
@@ -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,
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user