Skip to content

Commit 73c9aca

Browse files
committed
wip
1 parent 11ee38c commit 73c9aca

4 files changed

Lines changed: 81 additions & 63 deletions

File tree

modules/papyrus/checker/checker.v

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ fn (c &Checker) get_type_name(typ ast.Type) string {
6969
return c.table.get_type_symbol(typ).name
7070
}
7171

72+
// TODO rename to can_assign / valid_value_for_type
7273
//может ли тип var_typ иметь значение с типом value_typ
7374
pub fn (mut c Checker) valid_type(var_typ ast.Type, value_typ ast.Type) bool {
7475
assert var_typ != 0
@@ -103,12 +104,22 @@ pub fn (mut c Checker) can_autocast(from_type ast.Type, to_type ast.Type) bool {
103104
assert from_type != to_type
104105
from_sym := c.table.get_type_symbol(from_type)
105106
to_sym := c.table.get_type_symbol(to_type)
106-
assert from_sym.kind != .placeholder, from_sym.name
107-
assert to_sym.kind != .placeholder, to_sym.name
107+
108+
/*
109+
if from_sym.kind == .placeholder {
110+
print_backtrace()
111+
}
112+
113+
if to_sym.kind == .placeholder {
114+
print_backtrace()
115+
}*/
116+
117+
assert from_sym.kind != .placeholder, 'from_sym.kind == .placeholder, from_sym.name: ${from_sym.name}, to_sym.name: ${to_sym.name}'
118+
assert to_sym.kind != .placeholder, 'to_sym.kind == .placeholder, from_sym.name: ${from_sym.name}, to_sym.name: ${to_sym.name}'
108119

109120
match to_sym.kind {
110121
.placeholder {
111-
util.compiler_error(msg: "placeholder type symbol / invalid type in can_autocast", phase: "checker", prefs: c.pref, file: @FILE, func: @FN, line: @LINE)
122+
return false
112123
}
113124
.none_ {
114125
return false

modules/papyrus/checker/checker_expr.v

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
8888
node.is_object_var = true
8989
return node.typ
9090
}
91+
92+
c.error("undefined identifier `${node.name}`", node.pos)
9193

92-
c.error("variable declaration not found: `${node.name}`", node.pos)
9394
return ast.none_type
9495
}
9596
ast.CallExpr {
@@ -139,11 +140,18 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
139140
}
140141
else {
141142
if typ := c.find_var_or_property_type(node.typ, node.field_name) {
143+
if !c.type_is_valid(typ) {
144+
prop_var_type_name := c.get_type_name(typ)
145+
accessor_type := c.get_type_name(node.typ)
146+
c.error("invalid type `${prop_var_type_name}` for property or variable `${node.field_name}` in `${accessor_type}`", node.pos)
147+
return ast.none_type
148+
}
149+
142150
node.typ = typ
143151
return typ
144152
}
145153

146-
c.error("`${sym.obj_name}.${node.field_name}` property declaration not found", node.pos)
154+
c.error("field or property `${node.field_name}` not found", node.pos)
147155
return ast.none_type
148156
}
149157

@@ -448,7 +456,13 @@ pub fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
448456
arg_typ := c.expr(mut node.args[i].expr)
449457
node.args[i].typ = arg_typ
450458
func_arg_type := func.params[i].typ
451-
459+
460+
if !c.type_is_valid(arg_typ) {
461+
c.error("invalid type in function argument", node.args[i].pos)
462+
i++
463+
continue
464+
}
465+
452466
if c.valid_type(func_arg_type, arg_typ) {}
453467
else if c.can_autocast(arg_typ, func_arg_type) {
454468
node.args[i].expr = c.cast_to_type(node.args[i].expr, arg_typ, func_arg_type)

modules/papyrus/checker/checker_stmt.v

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,51 +54,52 @@ fn (mut c Checker) top_stmt(mut node ast.TopStmt) {
5454
c.var_decl(mut node)
5555
}
5656
ast.PropertyDecl {
57-
if c.type_is_valid(node.typ) {
58-
c.inside_property = true
57+
if !c.type_is_valid(node.typ) {
58+
type_name := c.get_type_name(node.typ)
59+
c.error("invalid type `${type_name}` for property `${node.name}`", node.pos)
60+
return
61+
}
5962

60-
if node.expr !is ast.EmptyExpr {
61-
if !node.expr.is_literal() {
62-
c.error("expression in object property can only be a literal", node.pos)
63-
}
63+
c.inside_property = true
6464

65-
left_type := node.typ
66-
mut right_type := c.expr(mut node.expr)
65+
if node.expr !is ast.EmptyExpr {
66+
if !node.expr.is_literal() {
67+
c.error("expression in object property can only be a literal", node.pos)
68+
}
6769

68-
if c.valid_prop_type(left_type, right_type) {}
70+
left_type := node.typ
71+
mut right_type := c.expr(mut node.expr)
72+
73+
if c.valid_prop_type(left_type, right_type) {}
74+
else {
75+
mb_new_expr := c.compile_time_cast_to_type(node.expr, right_type, left_type)
76+
if new_expr := mb_new_expr {
77+
node.expr = new_expr
78+
}
6979
else {
70-
mb_new_expr := c.compile_time_cast_to_type(node.expr, right_type, left_type)
71-
if new_expr := mb_new_expr {
72-
node.expr = new_expr
73-
}
74-
else {
75-
ltype_name := c.get_type_name(left_type)
76-
rtype_name := c.get_type_name(right_type)
77-
c.error("value with type `${rtype_name}` cannot be assigned to a property with type `${ltype_name}`", node.pos)
78-
}
80+
ltype_name := c.get_type_name(left_type)
81+
rtype_name := c.get_type_name(right_type)
82+
c.error("value with type `${rtype_name}` cannot be assigned to a property with type `${ltype_name}`", node.pos)
7983
}
8084
}
85+
}
8186

82-
if mut node.read is ast.FnDecl {
83-
c.top_stmt(mut &node.read)
84-
}
87+
if mut node.read is ast.FnDecl {
88+
c.top_stmt(mut &node.read)
89+
}
8590

86-
if mut node.write is ast.FnDecl {
87-
c.top_stmt(mut &node.write)
88-
}
91+
if mut node.write is ast.FnDecl {
92+
c.top_stmt(mut &node.write)
93+
}
8994

90-
sym := c.table.get_type_symbol(c.cur_obj)
91-
if t_prop := sym.find_property(node.name) {
92-
if t_prop.pos.pos != node.pos.pos {
93-
c.error("property with this name already exists", node.pos)
94-
}
95+
sym := c.table.get_type_symbol(c.cur_obj)
96+
if t_prop := sym.find_property(node.name) {
97+
if t_prop.pos.pos != node.pos.pos {
98+
c.error("property with this name already exists", node.pos)
9599
}
96-
97-
c.inside_property = false
98-
}
99-
else {
100-
c.error("invalid type in property declaration", node.pos)
101100
}
101+
102+
c.inside_property = false
102103
}
103104
ast.Comment {}
104105
}
@@ -182,7 +183,7 @@ fn (mut c Checker) stmt(mut node ast.Stmt) {
182183
valid_obj_none_value := node.is_object_var && node.right is ast.NoneLiteral && (c.table.get_type_symbol(left_type).kind == .script || c.table.get_type_symbol(left_type).kind == .array)
183184

184185
if c.valid_type(left_type, right_type) || valid_obj_none_value {}
185-
else if c.can_autocast(right_type, left_type) {
186+
else if c.type_is_valid(left_type) && c.type_is_valid(right_type) && c.can_autocast(right_type, left_type) {
186187
node.right = c.cast_to_type(node.right, right_type, left_type)
187188
right_type = left_type
188189
}
@@ -240,7 +241,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
240241

241242
if !c.type_is_valid(param.typ) {
242243
type_name := c.get_type_name(param.typ)
243-
c.error("invalid type `${type_name}` in function parameter", node.pos)
244+
c.error("invalid type `${type_name}` for parameter #${i + 1} `${param.name}` in function `${node.name}`", node.pos)
244245
continue
245246
}
246247

modules/tests/ast_test.v

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,31 +1329,33 @@ fn test_fn_default_arg() {
13291329
assert errs[0].message == "TODO444"
13301330
}
13311331

1332-
fn test_call_expr_arg_with_invalid_type()
1332+
fn test_error_msg()
13331333
{
13341334
mut stmts := []ast.TopStmt{}
13351335
mut table := ast.new_table()
13361336
mut errs := []errors.Error{}
13371337
mut src := ""
1338-
/*
1338+
13391339
src = "
13401340
Function MyFunc(int n1, int n2)
13411341
MyFunc(foooo, 1)
13421342
EndFunction"
13431343

13441344
stmts, table, errs = compile_top_stmts_error(src)
1345-
assert errs.len == 1
1346-
assert errs[0].message == "TODO111"
1345+
assert errs.len == 2
1346+
assert errs[0].message == "undefined identifier `foooo`"
1347+
assert errs[1].message == "cannot convert type `None` to type `Int`"
13471348

13481349
src = "
13491350
Function MyFunc(int n1, int n2)
13501351
MyFunc(ABCD.foooo, 1)
13511352
EndFunction"
13521353

13531354
stmts, table, errs = compile_top_stmts_error(src)
1354-
assert errs.len == 1
1355-
assert errs[0].message == "TODO222"
1356-
*/
1355+
assert errs.len == 3
1356+
assert errs[0].message == "undefined identifier `ABCD`"
1357+
assert errs[1].message == "field or property `foooo` not found"
1358+
assert errs[2].message == "cannot convert type `None` to type `Int`"
13571359

13581360
src = "
13591361
InvalidType Property propWithInvalidType Auto
@@ -1362,17 +1364,7 @@ fn test_call_expr_arg_with_invalid_type()
13621364
EndFunction"
13631365

13641366
stmts, table, errs = compile_top_stmts_error(src)
1365-
assert errs.len == 1
1366-
assert errs[0].message == "TODO222"
1367-
}
1368-
1369-
/*
1370-
modules\tests\SexLabSources\sslActorAlias.psc:1434:20: Checker error: cannot convert type `Furniture` to type `Form`
1371-
1432 | FormList FrostExceptions = Config.FrostExceptions
1372-
1433 | if FrostExceptions
1373-
1434 | FrostExceptions.RemoveAddedForm(Config.BaseMarker)
1374-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1375-
1435 | endIf
1376-
1436 | Thread.RemoveFade()
1377-
1378-
*/
1367+
assert errs.len == 2
1368+
assert errs[0].message == "invalid type `InvalidType` for property `propWithInvalidType`"
1369+
assert errs[1].message == "invalid type in function argument"
1370+
}

0 commit comments

Comments
 (0)