GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/parse/scan1.c Lines: 412 421 97.9 %
Date: 2020-07-24 14:14:26 Branches: 387 450 86.0 %

Line Branch Exec Source
1
#include "gwion_util.h"
2
#include "gwion_ast.h"
3
#include "gwion_env.h"
4
#include "vm.h"
5
#include "traverse.h"
6
#include "template.h"
7
#include "parse.h"
8
9
ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
10
ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
11
12
12635
ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Decl *td) {
13
12635
  Type owner = env->class_def;
14
  do {
15
12646
    Type parent = t;
16
47545
    while(parent) {
17
22254
      if(parent == owner)
18
1
        ERR_B(td_pos(td), _("%s declared inside %s"), t->name, owner->name);
19
22253
      parent = parent->e->parent;
20
    }
21
12645
  } while((owner = owner->e->owner_class));
22
12634
  return GW_OK;
23
}
24
25
39
ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
26
78
  struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
27
39
    .scope=env->scope->depth, .flag=ae_flag_scan1 };
28
39
  return envset_run(&es, t);
29
}
30
31
47280
ANN static Type scan1_type(const Env env, Type_Decl* td) {
32
47280
  DECL_OO(const Type, type, = known_type(env, td))
33
47244
  const Type t = get_type(type);
34

47244
  if(!env->func && env->class_def && !GET_FLAG(td, ref))
35
12635
    CHECK_BO(type_cyclic(env, t, td))
36

47243
  if(!GET_FLAG(t, scan1) && t->e->def)
37
33
    CHECK_BO(ensure_scan1(env, t))
38
47243
  return type;
39
}
40
41
47222
ANN static Type void_type(const Env env, Type_Decl* td) {
42
47222
  DECL_OO(const Type, type, = scan1_type(env, td))
43
47187
  if(type->size)
44
47184
    return type;
45
3
  ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')..."))
46
}
47
48
22883
ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
49
22883
  if(decl->type)
50
13
    return decl->type;
51
22870
  DECL_OO(const Type ,t, = void_type(env, decl->td))
52

22838
  if(decl->td->xid == insert_symbol("auto") && decl->type)
53
    return decl->type;
54

22838
  if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
55
12590
    SET_FLAG(decl->td, member);
56

22838
  if(GET_FLAG(t, private) && t->e->owner != env->curr)
57
1
    ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
58

22837
  if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
59
1
    ERR_O(exp_self(decl)->pos, _("can't use protected type %s"), t->name)
60
22836
  return decl->type = t;
61
}
62
63
22856
static inline m_bool scan1_defined(const Env env, const Var_Decl var) {
64

22856
  if(((!env->class_def || env->scope->depth) ? nspc_lookup_value1 : nspc_lookup_value2)(env->curr, var->xid))
65
3
    ERR_B(var->pos, _("variable %s has already been defined in the same scope..."),
66
              s_name(var->xid))
67
22853
  return GW_OK;
68
}
69
70
22847
ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
71
22847
  Var_Decl_List list = decl->list;
72
  do {
73
22856
    const Var_Decl var = list->self;
74
22856
    CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
75
22856
    Type t = decl->type;
76
22856
    CHECK_BB(scan1_defined(env, var))
77
22853
    if(var->array) {
78
45
      if(var->array->exp) {
79
36
        if(GET_FLAG(decl->td, ref))
80
1
          ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n"
81
            "e.g: int @my_array[];\nnot: int @my_array[2];"))
82
35
        CHECK_BB(scan1_exp(env, var->array->exp))
83
      }
84
44
      t = array_type(env, decl->type, var->array->depth);
85

22808
    } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, ref)) {
86
1
      if(decl->td->xid == insert_symbol("auto"))
87
        SET_FLAG(decl->td, ref);
88
      else
89
1
        ERR_B(exp_self(decl)->pos, _("Type '%s' is abstract, declare as ref. (use @)"), t->name)
90
    }
91
22851
    const Value v = var->value = new_value(env->gwion->mp, t, s_name(var->xid));
92

22851
    if(SAFE_FLAG(env->class_def, struct) && !GET_FLAG(decl->td, static)) {
93
26
      v->from->offset = env->class_def->size;
94
26
      env->class_def->size += t->size;
95
    }
96
22851
    nspc_add_value(env->curr, var->xid, v);
97
22851
    v->flag = decl->td->flag;
98
22851
    v->type = t;
99

22851
    if(var->array && !var->array->exp)
100
9
      SET_FLAG(v, ref);
101
22851
    if(env->class_def) {
102
12623
      if(env->class_def->e->tuple)
103
12623
        tuple_contains(env, v);
104
10228
    } else if(!env->scope->depth)
105
9900
      SET_FLAG(v, global);
106
22851
    v->d.ptr = var->addr;
107
22851
    if(GET_FLAG(decl->td, global))
108
6
      SET_FLAG(v, abstract);
109
22851
    if(!env->scope->depth)
110
22516
      valuefrom(env, v->from);
111
22851
  } while((list = list->next));
112
22842
  ((Exp_Decl*)decl)->type = decl->list->self->value->type;
113
22842
  return GW_OK;
114
}
115
116
19
ANN int is_global(const Nspc nspc, Nspc global) {
117
19
  do if(nspc == global)
118
6
    return 1;
119
13
  while((global = global->parent));
120
2
  return 0;
121
}
122
123
22887
ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
124
22887
  CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
125
22883
  ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
126
22883
  CHECK_OB(decl->type)
127
22849
  if(GET_FLAG(decl->type, const))
128
    exp_setmeta(exp_self(decl), 1);
129
22849
  const m_bool global = GET_FLAG(decl->td, global);
130
22849
  if(global) {
131
8
    if(env->context)
132
7
      env->context->global = 1;
133
8
    if(!is_global(decl->type->e->owner, env->global_nspc))
134
2
      ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name)
135
  }
136
22847
  const m_uint scope = !global ? env->scope->depth : env_push_global(env);
137
22847
  const m_bool ret = scan1_decl(env, decl);
138
22847
  if(global)
139
6
    env_pop(env, scope);
140
22847
  return ret;
141
}
142
143
749
ANN static inline m_bool scan1_exp_binary(const Env env, const Exp_Binary* bin) {
144
749
  CHECK_BB(scan1_exp(env, bin->lhs))
145
738
  return scan1_exp(env, bin->rhs);
146
}
147
148
12
ANN static m_bool scan1_range(const Env env, Range *range) {
149
12
  if(range->start)
150
11
    CHECK_BB(scan1_exp(env, range->start))
151
12
  if(range->end)
152
8
    CHECK_BB(scan1_exp(env, range->end))
153
12
  return GW_OK;
154
}
155
156
4671
ANN static inline m_bool scan1_prim(const Env env, const Exp_Primary* prim) {
157

8153
  if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
158
3482
        prim->prim_type == ae_prim_interp)
159
1194
    return scan1_exp(env, prim->d.exp);
160

3477
  if(prim->prim_type == ae_prim_array && prim->d.array->exp)
161
22
    return scan1_exp(env, prim->d.array->exp);
162
3455
  if(prim->prim_type == ae_prim_range)
163
3
    return scan1_range(env, prim->d.range);
164
3452
  return GW_OK;
165
}
166
167
30
ANN static inline m_bool scan1_exp_array(const Env env, const Exp_Array* array) {
168
30
  CHECK_BB(scan1_exp(env, array->base))
169
30
  return scan1_exp(env, array->array->exp);
170
}
171
172
9
ANN static inline m_bool scan1_exp_slice(const Env env, const Exp_Slice* range) {
173
9
  CHECK_BB(scan1_exp(env, range->base))
174
9
  return scan1_range(env, range->range);
175
}
176
177
37
ANN static inline m_bool scan1_exp_cast(const Env env, const Exp_Cast* cast) {
178
37
  return scan1_exp(env, cast->exp);
179
}
180
181
38
ANN static m_bool scan1_exp_post(const Env env, const Exp_Postfix* post) {
182
38
  CHECK_BB(scan1_exp(env, post->exp))
183
38
  const m_str access = exp_access(post->exp);
184
38
  if(!access)
185
37
    return GW_OK;
186
1
  ERR_B(post->exp->pos, _("post operator '%s' cannot be used"
187
      " on %s data-type..."), s_name(post->op), access);
188
}
189
190
540
ANN static m_bool scan1_exp_call(const Env env, const Exp_Call* exp_call) {
191
540
  if(exp_call->tmpl)
192
33
    return GW_OK;
193
507
  CHECK_BB(scan1_exp(env, exp_call->func))
194
506
  const Exp args = exp_call->args;
195
506
  return args ? scan1_exp(env, args) : GW_OK;
196
}
197
198
552
ANN static inline m_bool scan1_exp_dot(const Env env, const Exp_Dot* member) {
199
552
  if(member->base->next)
200
1
    ERR_B(member->base->pos, _("can't use multiple expression"
201
      " in dot member base expression"))
202
551
  return scan1_exp(env, member->base);
203
}
204
205
10
ANN static m_bool scan1_exp_if(const Env env, const Exp_If* exp_if) {
206
10
  CHECK_BB(scan1_exp(env, exp_if->cond))
207

10
  CHECK_BB(scan1_exp(env, exp_if->if_exp ?: exp_if->cond))
208
10
  return scan1_exp(env, exp_if->else_exp);
209
}
210
211
147
ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
212

147
  if((unary->op == insert_symbol("spork") || unary->op == insert_symbol("fork")) && unary->code)
213
25
    { RET_NSPC(scan1_stmt(env, unary->code)) }
214
122
  return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
215
}
216
217
#define scan1_exp_lambda dummy_func
218

29687
HANDLE_EXP_FUNC(scan1, m_bool, Env)
219
220
11
ANN static inline m_bool _scan1_stmt_match_case(const restrict Env env, const Stmt_Match stmt) {
221
11
  CHECK_BB(scan1_exp(env, stmt->cond))
222
11
  if(stmt->when)
223
4
    CHECK_BB(scan1_exp(env, stmt->when))
224
11
  return scan1_stmt_list(env, stmt->list);
225
}
226
227
11
ANN static inline m_bool scan1_stmt_match_case(const restrict Env env, const Stmt_Match stmt) {
228
11
  RET_NSPC(_scan1_stmt_match_case(env, stmt))
229
}
230
231
7
ANN static inline m_bool _scan1_stmt_match(const restrict Env env, const Stmt_Match stmt) {
232
7
  if(stmt->where)
233
2
    CHECK_BB(scan1_stmt(env, stmt->where))
234
7
  Stmt_List list = stmt->list;
235
11
  do CHECK_BB(scan1_stmt_match_case(env, &list->stmt->d.stmt_match))
236
11
  while((list = list->next));
237
7
  return GW_OK;
238
}
239
240
7
ANN static inline m_bool scan1_stmt_match(const restrict Env env, const Stmt_Match stmt) {
241
7
  CHECK_BB(scan1_exp(env, stmt->cond))
242
7
  RET_NSPC(_scan1_stmt_match(env, stmt))
243
}
244
245
#define describe_ret_nspc(name, type, prolog, exp) describe_stmt_func(scan1, name, type, prolog, exp)
246

26
describe_ret_nspc(flow, Stmt_Flow,, !(scan1_exp(env, stmt->cond) < 0 ||
247
    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
248

6
describe_ret_nspc(varloop, Stmt_VarLoop,, !(scan1_exp(env, stmt->exp) < 0 ||
249
    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
250


11
describe_ret_nspc(for, Stmt_For,, !(scan1_stmt(env, stmt->c1) < 0 ||
251
    scan1_stmt(env, stmt->c2) < 0 ||
252
    (stmt->c3 && scan1_exp(env, stmt->c3) < 0) ||
253
    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
254

11
describe_ret_nspc(auto, Stmt_Auto,, !(scan1_exp(env, stmt->exp) < 0 ||
255
    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
256

8
describe_ret_nspc(loop, Stmt_Loop,, !(scan1_exp(env, stmt->cond) < 0 ||
257
    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
258


34
describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 ||
259
    scan1_stmt(env, stmt->if_body) < 0 ||
260
    (stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
261
262
224
ANN static inline m_bool scan1_stmt_code(const Env env, const Stmt_Code stmt) {
263
224
  if(stmt->stmt_list)
264
222
    { RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) }
265
2
  return GW_OK;
266
}
267
268
2767
ANN static inline m_bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) {
269
2767
  return stmt->val ? scan1_exp(env, stmt->val) : 1;
270
}
271
272
741
ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
273
741
  ID_List list = edef->list;
274
  do {
275
1516
    CHECK_BB(already_defined(env, list->xid, edef->pos))
276
1516
    const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid));
277
1516
    valuefrom(env, v->from);
278
1516
    if(env->class_def) {
279
28
      SET_FLAG(v, static);
280

28
      SET_ACCESS(edef, v)
281

28
      SET_ACCESS(edef, edef->t)
282
    }
283
1516
    SET_FLAG(v, const | ae_flag_enum | ae_flag_valid);
284
1516
    nspc_add_value(edef->t->e->owner, list->xid, v);
285
1516
    vector_add(&edef->values, (vtype)v);
286
1516
  } while((list = list->next));
287
741
  return GW_OK;
288
}
289
290
24351
ANN static Value arg_value(const Env env, const Arg_List list) {
291
24351
  const Var_Decl var = list->var_decl;
292
24351
  const Value v = new_value(env->gwion->mp, list->type, var->xid ? s_name(var->xid) : (m_str)__func__);
293
24351
  if(var->array)
294
9
    v->type = list->type = array_type(env, list->type, var->array->depth);
295
24351
  if(list->td)
296
24346
    v->flag = list->td->flag | ae_flag_abstract;
297
24351
  return v;
298
}
299
300
24359
ANN static m_bool scan1_args(const Env env, Arg_List list) {
301
  do {
302
24359
    const Var_Decl var = list->var_decl;
303
24359
    if(var->xid)
304
24355
      CHECK_BB(isres(env, var->xid, var->pos))
305
24357
    if(list->td)
306
24352
      CHECK_OB((list->type = void_type(env, list->td)))
307
24351
    var->value = arg_value(env, list);
308
24351
    nspc_add_value(env->curr, var->xid, var->value);
309
24351
  } while((list = list->next));
310
16979
  return GW_OK;
311
}
312
313
141
ANN static m_bool _scan1_fdef_base_tmpl(const Env env, Func_Base *base) {
314
141
  ID_List id = base->tmpl->list;
315
157
  do nspc_add_type(env->curr, id->xid, env->gwion->type[et_undefined]);
316
157
  while((id = id->next));
317
141
  CHECK_OB((base->ret_type = known_type(env, base->td)))
318
140
  if(base->args) {
319
88
    Arg_List arg = base->args;
320
124
    do CHECK_OB(known_type(env, arg->td))
321
123
    while((arg = arg->next));
322
  }
323
139
  return GW_OK;
324
}
325
326
141
ANN static m_bool scan1_fdef_base_tmpl(const Env env, Func_Base *base) {
327
141
  nspc_push_type(env->gwion->mp, env->curr);
328
141
  const m_bool ret = _scan1_fdef_base_tmpl(env, base);
329
141
  nspc_pop_type(env->gwion->mp, env->curr);
330
141
  return ret;
331
}
332
333
74
ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
334
74
  if(tmpl_base(fptr->base->tmpl))
335
16
    return scan1_fdef_base_tmpl(env, fptr->base);
336
58
  if(!fptr->base->func) {
337
    fptr->base->func = nspc_lookup_value0(env->curr, fptr->base->xid)->d.func_ref;
338
    fptr->type = nspc_lookup_type0(env->curr, fptr->base->xid);
339
  }
340
58
  const Func_Def fdef = fptr->base->func->def;
341
58
  CHECK_OB((fdef->base->ret_type = scan1_type(env, fdef->base->td)))
342
56
  if(!fdef->base->args)
343
30
    return GW_OK;
344
26
  RET_NSPC(scan1_args(env, fdef->base->args))
345
}
346
347
751
ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
348
751
  if(!tdef->type)
349
    tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
350
751
  if(!tdef->type->e->def)return GW_OK;
351
8
  return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type->e->def) : GW_OK;
352
}
353
354
37
ANN static m_bool scan1_union_def_action(const Env env, const Union_Def udef,
355
    const Decl_List l) {
356
37
  const Exp_Decl decl = l->self->d.exp_decl;
357
37
  SET_FLAG(decl.td, valid | udef->flag);
358
37
  const m_bool global = GET_FLAG(udef, global);
359
37
  if(global)
360
6
    UNSET_FLAG(decl.td, global);
361
37
  if(GET_FLAG(udef, member))
362
3
    SET_FLAG(decl.td, member);
363
34
  else if(GET_FLAG(udef, static))
364
4
    SET_FLAG(decl.td, static);
365
37
  CHECK_BB(scan1_exp(env, l->self))
366
367
35
  Var_Decl_List list = decl.list;
368
35
  do ADD_REF(list->self->value)
369
35
  while((list = list->next));
370
371
35
  if(global)
372
6
    SET_FLAG(decl.td, global);
373
35
  return GW_OK;
374
}
375
376
37
ANN static inline m_bool scan1_union_def_inner_loop(const Env env, const Union_Def udef, Decl_List l) {
377
37
  do CHECK_BB(scan1_union_def_action(env, udef, l))
378
35
  while((l = l->next));
379
18
  return GW_OK;
380
}
381
382
20
ANN static m_bool scan1_union_def_inner(const Env env, const Union_Def udef) {
383

20
  if(udef->tmpl && udef->tmpl->call)
384
3
    CHECK_BB(template_push_types(env, udef->tmpl))
385
20
  const m_bool ret = scan1_union_def_inner_loop(env, udef, udef->l);
386

20
  if(udef->tmpl && udef->tmpl->call)
387
3
    nspc_pop_type(env->gwion->mp, env->curr);
388
20
  return ret;
389
}
390
391
24
ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
392
24
  if(tmpl_base(udef->tmpl))
393
4
    return GW_OK;
394
20
  const m_uint scope = union_push(env, udef);
395

20
  if(udef->xid || udef->type_xid) {
396
12
    UNSET_FLAG(udef, private);
397
12
    UNSET_FLAG(udef, protect);
398
  }
399
20
  const m_bool ret = scan1_union_def_inner(env, udef);
400
20
  union_pop(env, udef, scope);
401
20
  union_flag(udef, ae_flag_scan1);
402
20
  return ret;
403
}
404
405
#define scan1_stmt_while    scan1_stmt_flow
406
#define scan1_stmt_until    scan1_stmt_flow
407
#define scan1_stmt_continue (void*)dummy_func
408
#define scan1_stmt_break    (void*)dummy_func
409
#define scan1_stmt_jump     (void*)dummy_func
410
#define scan1_stmt_return   scan1_stmt_exp
411
#define scan1_stmt_pp       (void*)dummy_func
412
DECL_STMT_FUNC(scan1, m_bool, Env)
413
414
3129
ANN static inline m_bool scan1_stmt(const Env env, const Stmt stmt) {
415
3129
  return scan1_stmt_func[stmt->stmt_type](env, &stmt->d);
416
}
417
418
2972
ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
419
  do {
420
2972
    CHECK_BB(scan1_stmt(env, l->stmt))
421
2926
    if(l->next) {
422
1774
      if(l->stmt->stmt_type != ae_stmt_return) {
423

3297
        if(l->next->stmt->stmt_type == ae_stmt_exp &&
424
1525
          !l->next->stmt->d.stmt_exp.val) {
425
4
           Stmt_List next = l->next;
426
4
           l->next = l->next->next;
427
4
           next->next = NULL;
428
4
           free_stmt_list(env->gwion->mp, next);
429
        }
430
      } else {
431
2
        Stmt_List tmp = l->next;
432
2
        l->next = NULL;
433
2
        free_stmt_list(env->gwion->mp, tmp);
434
      }
435
    }
436
2926
  } while((l = l->next));
437
1158
  return GW_OK;
438
}
439
440
11
ANN static m_bool class_internal(const Env env, const Func_Base *base) {
441
11
  if(!env->class_def)
442
1
    ERR_B(td_pos(base->td), _("'%s' must be in class def!!"), s_name(base->xid))
443
10
  if(base->args)
444
1
    ERR_B(td_pos(base->td), _("'%s' must not have args"), s_name(base->xid))
445
9
  if(base->ret_type != env->gwion->type[et_void])
446
1
    ERR_B(td_pos(base->td), _("'%s' must return 'void'"), s_name(base->xid))
447
8
  return GW_OK;
448
}
449
450
6
ANN static inline m_bool scan_internal_arg(const Env env, const Func_Base *base) {
451

6
  if(base->args && !base->args->next)
452
5
    return GW_OK;
453
1
  ERR_B(td_pos(base->td), _("'%s' must have one (and only one) argument"), s_name(base->xid))
454
}
455
456
3
ANN static inline m_bool scan_internal_int(const Env env, const Func_Base *base) {
457
3
    CHECK_BB(scan_internal_arg(env, base))
458
3
    if(isa(base->ret_type, env->gwion->type[et_int]) > 0)
459
2
      return GW_OK;
460
1
    ERR_B(td_pos(base->td), _("'%s' must return 'int'"), s_name(base->xid))
461
}
462
463
22
ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
464
22
  const Symbol op = base->xid;
465

22
  if(op == insert_symbol("@dtor") || op == insert_symbol("@gack"))
466
11
    return class_internal(env, base);
467
11
  if(op == insert_symbol("@implicit"))
468
3
    return scan_internal_arg(env, base);
469

14
  if(op == insert_symbol("@conditionnal") ||
470
6
     op == insert_symbol("@unconditionnal"))
471
3
    return scan_internal_int(env, base);
472
5
  return GW_OK;
473
}
474
475
209
ANN static m_bool scan1_fdef_args(const Env env, Arg_List list) {
476
  do {
477
209
    Nspc nspc = env->curr;
478
923
    do if(nspc_lookup_value0(nspc, list->var_decl->xid))
479
       ERR_B(list->var_decl->pos, _("argument '%s' shadows a previuosly defined variable"),
480
            s_name(list->var_decl->xid))
481
923
    while((nspc = nspc->parent));
482
209
  } while((list = list->next));
483
162
  return GW_OK;
484
}
485
486
43386
ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
487
43386
  if(fdef->base->args) {
488
16961
    if(!GET_FLAG(fdef, builtin))
489
162
      CHECK_BB(scan1_fdef_args(env, fdef->base->args))
490
16961
    CHECK_BB(scan1_args(env, fdef->base->args))
491
  }
492

43380
  if(!GET_FLAG(fdef, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
493
232
    CHECK_BB(scan1_stmt_list(env, fdef->d.code->d.stmt_code.stmt_list))
494
43379
  return GW_OK;
495
}
496
497
43393
ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
498
43393
  if(fdef->base->td)
499
43385
    CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
500
43391
  if(GET_FLAG(fdef, typedef))
501
22
    CHECK_BB(scan_internal(env, fdef->base))
502

43369
  else if(GET_FLAG(fdef, op) && env->class_def)
503
2
    SET_FLAG(fdef, static);
504
43386
  RET_NSPC(scan1_fbody(env, fdef))
505
  return GW_OK;
506
}
507
508
43522
ANN static inline m_bool scan1_fdef_defined(const Env env, const Func_Def fdef) {
509
43522
  const Value v = nspc_lookup_value1(env->curr, fdef->base->xid);
510
43522
  if(!v)
511
34678
    return GW_OK;
512
8844
  if(isa(actual_type(env->gwion, v->type), env->gwion->type[et_function]) > 0)
513
8843
    return GW_OK;
514
1
  ERR_B(fdef->pos, _("function '%s' has already been defined in the same scope..."),
515
       s_name(fdef->base->xid))
516
}
517
518
43525
ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
519
43525
  if(fdef->base->td)
520
43517
    CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td)))
521
43522
  CHECK_BB(scan1_fdef_defined(env, fdef))
522
43521
  if(tmpl_base(fdef->base->tmpl))
523
125
    return scan1_fdef_base_tmpl(env, fdef->base);
524
43396
  struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func;
525
43396
  env->func = &fake;
526
43396
  ++env->scope->depth;
527
43396
  const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef);
528
43396
  --env->scope->depth;
529
43396
  env->func = former;
530
43396
  return ret;
531
}
532
533
1380
HANDLE_SECTION_FUNC(scan1, m_bool, Env)
534
535
72
ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
536
72
  const Type parent = known_type(env, tdef->ext);
537
72
  CHECK_OO((tdef->type->e->parent = parent));
538
72
  Type t = parent;
539
248
  do if(tdef->type == t)
540
      ERR_O(td_pos(tdef->ext), _("recursive (%s <= %s) class declaration."), tdef->type->name, t->name)
541
248
  while((t = t->e->parent));
542
72
  return parent;
543
}
544
545
72
ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
546
72
  const loc_t pos = td_pos(cdef->base.ext);
547
72
  if(cdef->base.ext->array)
548
9
    CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
549
72
  DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
550
72
  if(isa(parent, env->gwion->type[et_object]) < 0)
551
1
    ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
552

71
  if(parent->e->def && !GET_FLAG(parent, scan1))
553
6
    CHECK_BB(ensure_scan1(env, parent))
554
71
  if(type_ref(parent))
555
1
    ERR_B(pos, _("can't use ref type in class extend"))
556
70
  if(GET_FLAG(parent, nonnull))
557
1
    ERR_B(pos, _("can't use nonnull type in class extend"))
558
69
  return GW_OK;
559
}
560
561
72
ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
562

72
  if(cdef->base.tmpl && cdef->base.tmpl->list)
563
24
    CHECK_BB(template_push_types(env, cdef->base.tmpl))
564
72
  const m_bool ret = scan1_parent(env, cdef);
565

72
  if(cdef->base.tmpl && cdef->base.tmpl->list)
566
24
    nspc_pop_type(env->gwion->mp, env->curr);
567
72
  return ret;
568
}
569
570
293
ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
571
293
  if(tmpl_base(cdef->base.tmpl))
572
22
    return GW_OK;
573
271
  const Type t = cdef->base.type;
574
271
  if(GET_FLAG(t, scan1))
575
2
    return GW_OK;
576
269
  SET_FLAG(t, scan1);
577

269
  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan1))
578
    CHECK_BB(ensure_scan1(env, t->e->owner_class))
579
269
  SET_FLAG(cdef->base.type, scan1);
580
269
  if(cdef->base.ext)
581
72
    CHECK_BB(cdef_parent(env, cdef))
582
266
  if(cdef->body)
583
219
    CHECK_BB(env_body(env, cdef, scan1_section))
584
258
  return GW_OK;
585
}
586
587
1005
ANN m_bool scan1_ast(const Env env, Ast ast) {
588
1005
  do CHECK_BB(scan1_section(env, ast->section))
589
941
  while((ast = ast->next));
590
552
  return GW_OK;
591
}