Add type checker
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
parent
537d93ced1
commit
da19db1b23
36
ast.odin
36
ast.odin
@ -18,6 +18,8 @@ NodeKind :: enum {
|
||||
IndexAccess,
|
||||
FunctionCall,
|
||||
VariableDeclaration,
|
||||
Cast,
|
||||
BitwiseCast,
|
||||
|
||||
//
|
||||
Function,
|
||||
@ -37,6 +39,7 @@ Node :: struct {
|
||||
children: [dynamic]^Node,
|
||||
value: TokenValue,
|
||||
value_token_kind: TokenKind,
|
||||
return_type: ^Type,
|
||||
}
|
||||
|
||||
node_create_value :: proc(kind: NodeKind, range: TextRange, value: TokenValue) -> (ret: ^Node) {
|
||||
@ -171,6 +174,9 @@ node_print :: proc(node: ^Node, indent := 0) {
|
||||
if node.value_token_kind != .Invalid {
|
||||
fmt.printf("{} ", node.value_token_kind)
|
||||
}
|
||||
if node.return_type != nil {
|
||||
fmt.printf("-> {} ", node.return_type)
|
||||
}
|
||||
fmt.println("")
|
||||
|
||||
for child in node.children {
|
||||
@ -265,6 +271,36 @@ node_create_variable :: proc(
|
||||
return
|
||||
}
|
||||
|
||||
node_create_cast :: proc(
|
||||
range: TextRange,
|
||||
value, type_: ^Node,
|
||||
) -> (
|
||||
ret: ^Node,
|
||||
) {
|
||||
ret = new(Node)
|
||||
ret^ = {
|
||||
kind = .Cast,
|
||||
range = range,
|
||||
children = {value, type_},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
node_create_bitwise_cast :: proc(
|
||||
range: TextRange,
|
||||
value, type_: ^Node,
|
||||
) -> (
|
||||
ret: ^Node,
|
||||
) {
|
||||
ret = new(Node)
|
||||
ret^ = {
|
||||
kind = .BitwiseCast,
|
||||
range = range,
|
||||
children = {value, type_},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
node_create_struct_enum_or_union :: proc(
|
||||
range: TextRange,
|
||||
kind: NodeKind,
|
||||
|
57
lexer.odin
57
lexer.odin
@ -306,10 +306,59 @@ lexer_read_identifier :: proc(lexer: ^Lexer) -> Token {
|
||||
lexer_advance(lexer)
|
||||
}
|
||||
|
||||
if compare_dyn_arr_string(
|
||||
&str,
|
||||
"fn",
|
||||
) {return token_create(.Function, crange)} else if compare_dyn_arr_string(&str, "struct") {return token_create(.Struct, crange)} else if compare_dyn_arr_string(&str, "enum") {return token_create(.Enum, crange)} else if compare_dyn_arr_string(&str, "union") {return token_create(.Union, crange)} else if compare_dyn_arr_string(&str, "type") {return token_create(.Type, crange)} else if compare_dyn_arr_string(&str, "use") {return token_create(.Use, crange)} else if compare_dyn_arr_string(&str, "pub") {return token_create(.Pub, crange)} else if compare_dyn_arr_string(&str, "let") {return token_create(.Let, crange)} else if compare_dyn_arr_string(&str, "mut") {return token_create(.Mut, crange)} else if compare_dyn_arr_string(&str, "as") {return token_create(.As, crange)} else if compare_dyn_arr_string(&str, "in") {return token_create(.In, crange)} else if compare_dyn_arr_string(&str, "if") {return token_create(.If, crange)} else if compare_dyn_arr_string(&str, "else") {return token_create(.Else, crange)} else if compare_dyn_arr_string(&str, "elif") {return token_create(.Elif, crange)} else if compare_dyn_arr_string(&str, "for") {return token_create(.For, crange)} else if compare_dyn_arr_string(&str, "break") {return token_create(.Break, crange)} else if compare_dyn_arr_string(&str, "continue") {return token_create(.Continue, crange)} else if compare_dyn_arr_string(&str, "switch") {return token_create(.Switch, crange)} else if compare_dyn_arr_string(&str, "case") {return token_create(.Case, crange)} else if compare_dyn_arr_string(&str, "ret") {return token_create(.Ret, crange)} else if compare_dyn_arr_string(&str, "static") {return token_create(.Static, crange)} else if compare_dyn_arr_string(&str, "defer") {return token_create(.Defer, crange)} else if compare_dyn_arr_string(&str, "let") {return token_create(.Let, crange)} else if compare_dyn_arr_string(&str, "and") {return token_create(.And, crange)} else if compare_dyn_arr_string(&str, "or") {return token_create(.Or, crange)}
|
||||
if compare_dyn_arr_string(&str, "fn") {
|
||||
return token_create(.Function, crange)
|
||||
} else if compare_dyn_arr_string(&str, "struct") {
|
||||
return token_create(.Struct, crange)
|
||||
} else if compare_dyn_arr_string(&str, "enum") {
|
||||
return token_create(.Enum, crange)
|
||||
} else if compare_dyn_arr_string(&str, "union") {
|
||||
return token_create(.Union, crange)
|
||||
} else if compare_dyn_arr_string(&str, "type") {
|
||||
return token_create(.Type, crange)
|
||||
} else if compare_dyn_arr_string(&str, "use") {
|
||||
return token_create(.Use, crange)
|
||||
} else if compare_dyn_arr_string(&str, "pub") {
|
||||
return token_create(.Pub, crange)
|
||||
} else if compare_dyn_arr_string(&str, "let") {
|
||||
return token_create(.Let, crange)
|
||||
} else if compare_dyn_arr_string(&str, "mut") {
|
||||
return token_create(.Mut, crange)
|
||||
} else if compare_dyn_arr_string(&str, "as") {
|
||||
return token_create(.As, crange)
|
||||
} else if compare_dyn_arr_string(&str, "bitwise_as") {
|
||||
return token_create(.BitwiseAs, crange)
|
||||
} else if compare_dyn_arr_string(&str, "in") {
|
||||
return token_create(.In, crange)
|
||||
} else if compare_dyn_arr_string(&str, "if") {
|
||||
return token_create(.If, crange)
|
||||
} else if compare_dyn_arr_string(&str, "else") {
|
||||
return token_create(.Else, crange)
|
||||
} else if compare_dyn_arr_string(&str, "elif") {
|
||||
return token_create(.Elif, crange)
|
||||
} else if compare_dyn_arr_string(&str, "for") {
|
||||
return token_create(.For, crange)
|
||||
} else if compare_dyn_arr_string(&str, "break") {
|
||||
return token_create(.Break, crange)
|
||||
} else if compare_dyn_arr_string(&str, "continue") {
|
||||
return token_create(.Continue, crange)
|
||||
} else if compare_dyn_arr_string(&str, "switch") {
|
||||
return token_create(.Switch, crange)
|
||||
} else if compare_dyn_arr_string(&str, "case") {
|
||||
return token_create(.Case, crange)
|
||||
} else if compare_dyn_arr_string(&str, "ret") {
|
||||
return token_create(.Ret, crange)
|
||||
} else if compare_dyn_arr_string(&str, "static") {
|
||||
return token_create(.Static, crange)
|
||||
} else if compare_dyn_arr_string(&str, "defer") {
|
||||
return token_create(.Defer, crange)
|
||||
} else if compare_dyn_arr_string(&str, "let") {
|
||||
return token_create(.Let, crange)
|
||||
} else if compare_dyn_arr_string(&str, "and") {
|
||||
return token_create(.And, crange)
|
||||
} else if compare_dyn_arr_string(&str, "or") {
|
||||
return token_create(.Or, crange)
|
||||
}
|
||||
|
||||
return token_create_u8(.Identifier, str, crange)
|
||||
}
|
||||
|
@ -32,12 +32,14 @@ main :: proc() {
|
||||
parser := parser_create(lexer)
|
||||
|
||||
ast := parser_parse(&parser)
|
||||
type_check(ast, nil)
|
||||
if len(g_message_list) > 0 {
|
||||
for msg in g_message_list {
|
||||
fmt.printf("%s\n", msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
node_print(ast)
|
||||
}
|
||||
|
||||
|
10
parser.odin
10
parser.odin
@ -459,6 +459,14 @@ parser_parse_suffix :: proc(parser: ^Parser) -> ^Node {
|
||||
return node_create_unary(.Increment, range, lhs)
|
||||
} else if accept(parser, .Decrement) {
|
||||
return node_create_unary(.Decrement, range, lhs)
|
||||
} else if accept(parser, .As) {
|
||||
type := parser_parse_type(parser)
|
||||
range.end = type.range.end
|
||||
return node_create_cast(range, lhs, type)
|
||||
} else if accept(parser, .BitwiseAs) {
|
||||
type := parser_parse_type(parser)
|
||||
range.end = type.range.end
|
||||
return node_create_bitwise_cast(range, lhs, type)
|
||||
}
|
||||
return lhs
|
||||
}
|
||||
@ -519,6 +527,7 @@ parser_parse_factor :: proc(parser: ^Parser) -> (ret: ^Node) {
|
||||
parser.tok.kind != .CloseParen &&
|
||||
parser.tok.kind != .Semicolon &&
|
||||
parser.tok.kind != .Arrow &&
|
||||
parser.tok.kind != .Assign &&
|
||||
parser.tok.kind != .EOF {
|
||||
prev := parser.can_be_function
|
||||
parser.can_be_function = false
|
||||
@ -527,6 +536,7 @@ parser_parse_factor :: proc(parser: ^Parser) -> (ret: ^Node) {
|
||||
parser.tok.kind != .Semicolon &&
|
||||
parser.tok.kind != .Arrow &&
|
||||
parser.tok.kind != .EOF &&
|
||||
parser.tok.kind != .Assign &&
|
||||
parser_is_factor_token_or_prefix(parser.tok.kind) {
|
||||
append(&args, parser_parse_expression(parser))
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ TokenKind :: enum {
|
||||
Pub,
|
||||
Mut,
|
||||
As,
|
||||
BitwiseAs,
|
||||
In,
|
||||
If,
|
||||
Else,
|
||||
|
Loading…
x
Reference in New Issue
Block a user