@@ -155,6 +155,40 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
155
155
return has_main_fn
156
156
}
157
157
158
+ pub fn (mut c Checker) type_decl (node ast.TypeDecl) {
159
+ match node {
160
+ ast.AliasTypeDecl {
161
+ typ_sym := c.table.get_type_symbol (it .parent_type)
162
+ if typ_sym.kind == .placeholder {
163
+ c.error ("type `$typ_sym.name ` doesn't exist" , it .pos)
164
+ }
165
+ }
166
+ ast.FnTypeDecl {
167
+ typ_sym := c.table.get_type_symbol (it .typ)
168
+ fn_typ_info := typ_sym.info as table.FnType
169
+ fn_info := fn_typ_info.func
170
+ ret_sym := c.table.get_type_symbol (fn_info.return_type)
171
+ if ret_sym.kind == .placeholder {
172
+ c.error ("type `$ret_sym.name ` doesn't exist" , it .pos)
173
+ }
174
+ for arg in fn_info.args {
175
+ arg_sym := c.table.get_type_symbol (arg.typ)
176
+ if arg_sym.kind == .placeholder {
177
+ c.error ("type `$arg_sym.name ` doesn't exist" , it .pos)
178
+ }
179
+ }
180
+ }
181
+ ast.SumTypeDecl {
182
+ for typ in it .sub_types {
183
+ typ_sym := c.table.get_type_symbol (typ)
184
+ if typ_sym.kind == .placeholder {
185
+ c.error ("type `$typ_sym.name ` doesn't exist" , it .pos)
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+
158
192
pub fn (mut c Checker) struct_decl (decl ast.StructDecl) {
159
193
splitted_full_name := decl.name.split ('.' )
160
194
is_builtin := splitted_full_name[0 ] == 'builtin'
@@ -1088,6 +1122,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
1088
1122
it .pos)
1089
1123
}
1090
1124
}
1125
+ // ast.Attr {}
1091
1126
ast.AssignStmt {
1092
1127
c.assign_stmt (mut it )
1093
1128
}
@@ -1099,7 +1134,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
1099
1134
c.error ('$it.tok.lit statement not within a loop' , it .tok.position ())
1100
1135
}
1101
1136
}
1102
- // ast.Attr {}
1103
1137
ast.CompIf {
1104
1138
// c.expr(it.cond)
1105
1139
c.stmts (it .stmts)
@@ -1170,17 +1204,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
1170
1204
}
1171
1205
c.returns = false
1172
1206
}
1173
- ast.ForStmt {
1174
- c.in_for_count++
1175
- typ := c.expr (it .cond)
1176
- if ! it .is_inf && typ.idx () != table.bool_type_idx {
1177
- c.error ('non-bool used as for condition' , it .pos)
1178
- }
1179
- // TODO: update loop var type
1180
- // how does this work currenly?
1181
- c.stmts (it .stmts)
1182
- c.in_for_count--
1183
- }
1184
1207
ast.ForCStmt {
1185
1208
c.in_for_count++
1186
1209
c.stmt (it .init)
@@ -1230,8 +1253,20 @@ fn (mut c Checker) stmt(node ast.Stmt) {
1230
1253
c.stmts (it .stmts)
1231
1254
c.in_for_count--
1232
1255
}
1256
+ ast.ForStmt {
1257
+ c.in_for_count++
1258
+ typ := c.expr (it .cond)
1259
+ if ! it .is_inf && typ.idx () != table.bool_type_idx {
1260
+ c.error ('non-bool used as for condition' , it .pos)
1261
+ }
1262
+ // TODO: update loop var type
1263
+ // how does this work currenly?
1264
+ c.stmts (it .stmts)
1265
+ c.in_for_count--
1266
+ }
1267
+ // ast.GlobalDecl {}
1233
1268
ast.GoStmt {
1234
- if ! is_call_expr (it .call_expr) {
1269
+ if ! (it .call_expr is ast.CallExpr ) {
1235
1270
c.error ('expression in `go` must be a function call' , it .call_expr.position ())
1236
1271
}
1237
1272
c.expr (it .call_expr)
@@ -1242,14 +1277,16 @@ fn (mut c Checker) stmt(node ast.Stmt) {
1242
1277
c.mod = it .name
1243
1278
c.is_builtin_mod = it .name == 'builtin'
1244
1279
}
1245
- // ast.GlobalDecl {}
1246
1280
ast.Return {
1247
1281
c.returns = true
1248
1282
c.return_stmt (mut it )
1249
1283
}
1250
1284
ast.StructDecl {
1251
1285
c.struct_decl (it )
1252
1286
}
1287
+ ast.TypeDecl {
1288
+ c.type_decl (it )
1289
+ }
1253
1290
ast.UnsafeStmt {
1254
1291
c.stmts (it .stmts)
1255
1292
}
@@ -1260,13 +1297,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
1260
1297
}
1261
1298
}
1262
1299
1263
- fn is_call_expr (expr ast.Expr) bool {
1264
- return match expr {
1265
- ast.CallExpr { true }
1266
- else { false }
1267
- }
1268
- }
1269
-
1270
1300
fn (mut c Checker) stmts (stmts []ast.Stmt) {
1271
1301
c.expected_type = table.void_type
1272
1302
for stmt in stmts {
0 commit comments