Add support for multiple field accesses in parser and type checker
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
parent
464532d9fe
commit
c5747a103e
@ -600,13 +600,30 @@ parser_parse_factor :: proc(parser: ^Parser) -> (ret: ^Node) {
|
|||||||
parser_next(parser)
|
parser_next(parser)
|
||||||
prev := parser.can_be_function
|
prev := parser.can_be_function
|
||||||
parser.can_be_function = false
|
parser.can_be_function = false
|
||||||
if accept(parser, .Dot) {
|
|
||||||
|
for accept(parser, .Dot) {
|
||||||
|
if parser.tok.kind != .Identifier {
|
||||||
|
append(
|
||||||
|
&g_message_list,
|
||||||
|
message_create(
|
||||||
|
.Error,
|
||||||
|
fmt.aprintf("Expected identifier after '.' but got {}", parser.tok.kind),
|
||||||
|
parser.tok.range,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
right := node_create_value(.Identifier, parser.tok.range, parser.tok.value)
|
||||||
|
parser_next(parser)
|
||||||
|
|
||||||
ret = node_create_field_access(
|
ret = node_create_field_access(
|
||||||
SourceLocation{{ret.range.range.start, parser.tok.range.range.start}, ret.range.file},
|
SourceLocation{{ret.range.range.start, right.range.range.end}, ret.range.file},
|
||||||
ret,
|
ret,
|
||||||
parser_parse_factor(parser),
|
right,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.can_be_function = prev
|
parser.can_be_function = prev
|
||||||
if parser.can_be_function &&
|
if parser.can_be_function &&
|
||||||
parser.tok.kind != .CloseParen &&
|
parser.tok.kind != .CloseParen &&
|
||||||
|
@ -236,50 +236,81 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
|||||||
lhs := ast.children[0]
|
lhs := ast.children[0]
|
||||||
rhs := ast.children[1]
|
rhs := ast.children[1]
|
||||||
// FIXME: Add support for nesting
|
// FIXME: Add support for nesting
|
||||||
if lhs.kind != .Identifier {
|
struct_: ^Struct
|
||||||
append(
|
if lhs.kind != .FieldAccess {
|
||||||
&g_message_list,
|
struct_var := scope_variable_lookup(lhs.value.([dynamic]u8))
|
||||||
message_create(.Error, fmt.aprintf("Field access lhs is not an identifier"), lhs.range),
|
if struct_var == nil {
|
||||||
)
|
append(
|
||||||
break
|
&g_message_list,
|
||||||
|
message_create(
|
||||||
|
.Error,
|
||||||
|
fmt.aprintf("Cannot find struct of name: `%s`", lhs.value.([dynamic]u8)),
|
||||||
|
lhs.range,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_ = scope_struct_lookup(struct_var.struct_type.name)
|
||||||
|
if struct_ == nil {
|
||||||
|
append(
|
||||||
|
&g_message_list,
|
||||||
|
message_create(
|
||||||
|
.Error,
|
||||||
|
fmt.aprintf("Cannot find struct of type name: `%s`", lhs.value.([dynamic]u8)),
|
||||||
|
lhs.range,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rhs.kind != .Identifier {
|
if rhs.kind != .Identifier {
|
||||||
append(
|
append(
|
||||||
&g_message_list,
|
&g_message_list,
|
||||||
message_create(.Error, fmt.aprintf("Field access rhs is not an identifier"), rhs.range),
|
message_create(.Error, fmt.aprintf("Field access rhs is not an identifier or field access: {}", rhs.kind), rhs.range),
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_var := scope_variable_lookup(lhs.value.([dynamic]u8))
|
if lhs.kind == .FieldAccess {
|
||||||
if struct_var == nil {
|
type_check(lhs, ast)
|
||||||
|
if lhs.return_type.kind != .Struct {
|
||||||
|
append(
|
||||||
|
&g_message_list,
|
||||||
|
message_create(
|
||||||
|
.Error,
|
||||||
|
fmt.aprintf("LHS is not a Struct type"),
|
||||||
|
lhs.range,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_ = scope_struct_lookup(lhs.return_type.struct_type.name)
|
||||||
|
if struct_ == nil {
|
||||||
|
append(
|
||||||
|
&g_message_list,
|
||||||
|
message_create(
|
||||||
|
.Error,
|
||||||
|
fmt.aprintf("Cannot find struct of type name: `%s`", lhs.value.([dynamic]u8)),
|
||||||
|
lhs.range,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else if lhs.kind != .Identifier {
|
||||||
append(
|
append(
|
||||||
&g_message_list,
|
&g_message_list,
|
||||||
message_create(
|
message_create(.Error, fmt.aprintf("Field access lhs is not an identifier or FieldAccess"), lhs.range),
|
||||||
.Error,
|
|
||||||
fmt.aprintf("Cannot find struct of name: `%s`", lhs.value.([dynamic]u8)),
|
|
||||||
rhs.range,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_ := scope_struct_lookup(struct_var.struct_type.name)
|
|
||||||
if struct_ == nil {
|
|
||||||
append(
|
|
||||||
&g_message_list,
|
|
||||||
message_create(
|
|
||||||
.Error,
|
|
||||||
fmt.aprintf("Cannot find struct of type name: `%s`", lhs.value.([dynamic]u8)),
|
|
||||||
rhs.range,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
found_field := false
|
|
||||||
struct_index: u64 = 0
|
struct_index: u64 = 0
|
||||||
|
found_field := false
|
||||||
|
fmt.println("==")
|
||||||
for &field, i in struct_.fields {
|
for &field, i in struct_.fields {
|
||||||
|
fmt.printf("- %s\n", field.name)
|
||||||
if compare_dyn_arrs(&field.name, &rhs.value.([dynamic]u8)) {
|
if compare_dyn_arrs(&field.name, &rhs.value.([dynamic]u8)) {
|
||||||
ast.return_type = field.type
|
ast.return_type = field.type
|
||||||
found_field = true
|
found_field = true
|
||||||
@ -436,11 +467,11 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if ast.value_token_kind == .Equals ||
|
} else if ast.value_token_kind == .Equals ||
|
||||||
ast.value_token_kind == .NotEquals ||
|
ast.value_token_kind == .NotEquals ||
|
||||||
ast.value_token_kind == .GreaterThan ||
|
ast.value_token_kind == .GreaterThan ||
|
||||||
ast.value_token_kind == .GreaterThanOrEqual ||
|
ast.value_token_kind == .GreaterThanOrEqual ||
|
||||||
ast.value_token_kind == .LessThan ||
|
ast.value_token_kind == .LessThan ||
|
||||||
ast.value_token_kind == .LessThanOrEqual {
|
ast.value_token_kind == .LessThanOrEqual {
|
||||||
ast.return_type = type_create_integer(1, true)
|
ast.return_type = type_create_integer(1, true)
|
||||||
}
|
}
|
||||||
// FIXME: Verify that the operation is possible
|
// FIXME: Verify that the operation is possible
|
||||||
|
Loading…
x
Reference in New Issue
Block a user