mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Support matrix type in core:odin
This commit is contained in:
@@ -224,6 +224,15 @@ Slice_Expr :: struct {
|
|||||||
close: tokenizer.Pos,
|
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 {
|
Call_Expr :: struct {
|
||||||
using node: Expr,
|
using node: Expr,
|
||||||
inlining: Proc_Inlining,
|
inlining: Proc_Inlining,
|
||||||
@@ -739,3 +748,11 @@ Relative_Type :: struct {
|
|||||||
tag: ^Expr,
|
tag: ^Expr,
|
||||||
type: ^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:
|
case Index_Expr:
|
||||||
r.expr = clone(r.expr)
|
r.expr = clone(r.expr)
|
||||||
r.index = clone(r.index)
|
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:
|
case Deref_Expr:
|
||||||
r.expr = clone(r.expr)
|
r.expr = clone(r.expr)
|
||||||
case Slice_Expr:
|
case Slice_Expr:
|
||||||
@@ -275,7 +279,10 @@ clone_node :: proc(node: ^Node) -> ^Node {
|
|||||||
case Map_Type:
|
case Map_Type:
|
||||||
r.key = clone(r.key)
|
r.key = clone(r.key)
|
||||||
r.value = clone(r.value)
|
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:
|
case:
|
||||||
fmt.panicf("Unhandled node kind: %T", r)
|
fmt.panicf("Unhandled node kind: %T", r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,10 @@ walk :: proc(v: ^Visitor, node: ^Node) {
|
|||||||
case Index_Expr:
|
case Index_Expr:
|
||||||
walk(v, n.expr)
|
walk(v, n.expr)
|
||||||
walk(v, n.index)
|
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:
|
case Deref_Expr:
|
||||||
walk(v, n.expr)
|
walk(v, n.expr)
|
||||||
case Slice_Expr:
|
case Slice_Expr:
|
||||||
@@ -398,6 +402,10 @@ walk :: proc(v: ^Visitor, node: ^Node) {
|
|||||||
case Relative_Type:
|
case Relative_Type:
|
||||||
walk(v, n.tag)
|
walk(v, n.tag)
|
||||||
walk(v, n.type)
|
walk(v, n.type)
|
||||||
|
case Matrix_Type:
|
||||||
|
walk(v, n.row_count)
|
||||||
|
walk(v, n.column_count)
|
||||||
|
walk(v, n.elem)
|
||||||
|
|
||||||
case:
|
case:
|
||||||
fmt.panicf("ast.walk: unexpected node type %T", n)
|
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.underlying = underlying
|
||||||
bst.close = close.pos
|
bst.close = close.pos
|
||||||
return bst
|
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:
|
case .Asm:
|
||||||
tok := expect_token(p, .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
|
defer p.allow_range = prev_allow_range
|
||||||
p.allow_range = false
|
p.allow_range = false
|
||||||
|
|
||||||
indicies: [2]^ast.Expr
|
indices: [2]^ast.Expr
|
||||||
interval: tokenizer.Token
|
interval: tokenizer.Token
|
||||||
is_slice_op := false
|
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
|
// NOTE(bill): Do not err yet
|
||||||
break
|
break
|
||||||
case:
|
case:
|
||||||
indicies[0] = parse_expr(p, false)
|
indices[0] = parse_expr(p, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#partial switch p.curr_tok.kind {
|
#partial switch p.curr_tok.kind {
|
||||||
case .Ellipsis, .Range_Half, .Range_Full:
|
case .Ellipsis, .Range_Half, .Range_Full:
|
||||||
error(p, p.curr_tok.pos, "expected a colon, not a range")
|
error(p, p.curr_tok.pos, "expected a colon, not a range")
|
||||||
fallthrough
|
fallthrough
|
||||||
case .Colon:
|
case .Colon, .Comma/*matrix index*/:
|
||||||
interval = advance_token(p)
|
interval = advance_token(p)
|
||||||
is_slice_op = true
|
is_slice_op = true
|
||||||
if p.curr_tok.kind != .Close_Bracket && p.curr_tok.kind != .EOF {
|
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
|
p.expr_level -= 1
|
||||||
|
|
||||||
if is_slice_op {
|
if is_slice_op {
|
||||||
se := ast.new(ast.Slice_Expr, operand.pos, end_pos(close))
|
if interval.kind == .Comma {
|
||||||
se.expr = operand
|
if indices[0] == nil || indices[1] == nil {
|
||||||
se.open = open.pos
|
error(p, p.curr_tok.pos, "matrix index expressions require both row and column indices")
|
||||||
se.low = indicies[0]
|
}
|
||||||
se.interval = interval
|
se := ast.new(ast.Matrix_Index_Expr, operand.pos, end_pos(close))
|
||||||
se.high = indicies[1]
|
se.expr = operand
|
||||||
se.close = close.pos
|
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 {
|
} else {
|
||||||
ie := ast.new(ast.Index_Expr, operand.pos, end_pos(close))
|
ie := ast.new(ast.Index_Expr, operand.pos, end_pos(close))
|
||||||
ie.expr = operand
|
ie.expr = operand
|
||||||
ie.open = open.pos
|
ie.open = open.pos
|
||||||
ie.index = indicies[0]
|
ie.index = indices[0]
|
||||||
ie.close = close.pos
|
ie.close = close.pos
|
||||||
|
|
||||||
operand = ie
|
operand = ie
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ Token_Kind :: enum u32 {
|
|||||||
Asm, // asm
|
Asm, // asm
|
||||||
Inline, // inline
|
Inline, // inline
|
||||||
No_Inline, // no_inline
|
No_Inline, // no_inline
|
||||||
|
Matrix, // matrix
|
||||||
B_Keyword_End,
|
B_Keyword_End,
|
||||||
|
|
||||||
COUNT,
|
COUNT,
|
||||||
@@ -280,6 +281,7 @@ tokens := [Token_Kind.COUNT]string {
|
|||||||
"asm",
|
"asm",
|
||||||
"inline",
|
"inline",
|
||||||
"no_inline",
|
"no_inline",
|
||||||
|
"matrix",
|
||||||
"",
|
"",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,10 +301,10 @@ token_to_string :: proc(tok: Token) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
to_string :: proc(kind: Token_Kind) -> 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]
|
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))
|
n := int(u16(kind)-u16(Token_Kind.B_Custom_Keyword_Begin))
|
||||||
if n < len(custom_keyword_tokens) {
|
if n < len(custom_keyword_tokens) {
|
||||||
return custom_keyword_tokens[n]
|
return custom_keyword_tokens[n]
|
||||||
@@ -313,7 +315,7 @@ to_string :: proc(kind: Token_Kind) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is_literal :: proc(kind: Token_Kind) -> bool {
|
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 {
|
is_operator :: proc(kind: Token_Kind) -> bool {
|
||||||
#partial switch kind {
|
#partial switch kind {
|
||||||
@@ -327,13 +329,13 @@ is_operator :: proc(kind: Token_Kind) -> bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
is_assignment_operator :: proc(kind: Token_Kind) -> bool {
|
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 {
|
is_keyword :: proc(kind: Token_Kind) -> bool {
|
||||||
switch {
|
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
|
return true
|
||||||
case Token_Kind.B_Custom_Keyword_Begin < kind:
|
case .B_Custom_Keyword_Begin < kind:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user