@@ -187,6 +187,9 @@ void compileStmt(i64_array* program, Stmt* stmt)
187
187
symbol_y -> value_type == V_INT || symbol_y -> value_type == V_FLOAT
188
188
))
189
189
symbol_x -> value_type = symbol_y -> value_type ;
190
+
191
+ strongly_type (symbol_x , symbol_y , NULL , stmt -> v .assign_stmt -> y , symbol_x -> value_type );
192
+
190
193
switch (symbol_x -> value_type ) {
191
194
case V_BOOL :
192
195
push_instr (program , LII );
@@ -378,6 +381,8 @@ void compileStmt(i64_array* program, Stmt* stmt)
378
381
break ;
379
382
}
380
383
384
+ strongly_type (symbol , NULL , NULL , stmt -> v .assign_stmt -> y , symbol -> value_type );
385
+
381
386
switch (symbol -> type ) {
382
387
case K_STRING :
383
388
if (symbol -> value_type == V_REF ) {
@@ -1156,6 +1161,9 @@ unsigned short compileExpr(i64_array* program, Expr* expr)
1156
1161
Expr * expr = expr_list -> exprs [expr_list -> expr_count - i ];
1157
1162
enum ValueType value_type = compileExpr (program , expr ) - 1 ;
1158
1163
Symbol * parameter = function -> parameters [i - 1 ];
1164
+
1165
+ strongly_type (parameter , NULL , function , expr , value_type );
1166
+
1159
1167
enum Type type = parameter -> type ;
1160
1168
i64 addr = parameter -> addr ;
1161
1169
@@ -1682,24 +1690,28 @@ void compileDecl(i64_array* program, Decl* decl)
1682
1690
case VarDecl_kind : {
1683
1691
enum ValueType value_type = compileExpr (program , decl -> v .var_decl -> expr ) - 1 ;
1684
1692
enum Type type = compileSpec (program , decl -> v .var_decl -> type_spec );
1693
+ enum Type secondary_type = K_ANY ;
1694
+ if (decl -> v .var_decl -> type_spec -> v .type_spec -> sub_type_spec != NULL )
1695
+ secondary_type = decl -> v .var_decl -> type_spec -> v .type_spec -> type ;
1696
+ Symbol * symbol = NULL ;
1685
1697
1686
1698
switch (type ) {
1687
1699
case K_BOOL :
1688
- store_bool (
1700
+ symbol = store_bool (
1689
1701
program ,
1690
1702
decl -> v .var_decl -> ident -> v .ident -> name ,
1691
1703
false
1692
1704
);
1693
1705
break ;
1694
1706
case K_NUMBER :
1695
1707
if (value_type == V_FLOAT ) {
1696
- store_float (
1708
+ symbol = store_float (
1697
1709
program ,
1698
1710
decl -> v .var_decl -> ident -> v .ident -> name ,
1699
1711
false
1700
1712
);
1701
1713
} else {
1702
- store_int (
1714
+ symbol = store_int (
1703
1715
program ,
1704
1716
decl -> v .var_decl -> ident -> v .ident -> name ,
1705
1717
false
@@ -1727,7 +1739,7 @@ void compileDecl(i64_array* program, Decl* decl)
1727
1739
break ;
1728
1740
}
1729
1741
1730
- store_string (
1742
+ symbol = store_string (
1731
1743
program ,
1732
1744
decl -> v .var_decl -> ident -> v .ident -> name ,
1733
1745
len ,
@@ -1739,22 +1751,22 @@ void compileDecl(i64_array* program, Decl* decl)
1739
1751
case K_ANY : {
1740
1752
switch (value_type ) {
1741
1753
case V_BOOL :
1742
- store_bool (
1754
+ symbol = store_bool (
1743
1755
program ,
1744
1756
decl -> v .var_decl -> ident -> v .ident -> name ,
1745
1757
true
1746
1758
);
1747
1759
break ;
1748
1760
case V_INT : {
1749
- store_int (
1761
+ symbol = store_int (
1750
1762
program ,
1751
1763
decl -> v .var_decl -> ident -> v .ident -> name ,
1752
1764
true
1753
1765
);
1754
1766
break ;
1755
1767
}
1756
1768
case V_FLOAT : {
1757
- store_float (
1769
+ symbol = store_float (
1758
1770
program ,
1759
1771
decl -> v .var_decl -> ident -> v .ident -> name ,
1760
1772
true
@@ -1785,7 +1797,7 @@ void compileDecl(i64_array* program, Decl* decl)
1785
1797
break ;
1786
1798
}
1787
1799
1788
- store_string (
1800
+ symbol = store_string (
1789
1801
program ,
1790
1802
decl -> v .var_decl -> ident -> v .ident -> name ,
1791
1803
len ,
@@ -1795,19 +1807,19 @@ void compileDecl(i64_array* program, Decl* decl)
1795
1807
break ;
1796
1808
}
1797
1809
case V_LIST :
1798
- store_any (
1810
+ symbol = store_any (
1799
1811
program ,
1800
1812
decl -> v .var_decl -> ident -> v .ident -> name
1801
1813
);
1802
1814
break ;
1803
1815
case V_DICT :
1804
- store_any (
1816
+ symbol = store_any (
1805
1817
program ,
1806
1818
decl -> v .var_decl -> ident -> v .ident -> name
1807
1819
);
1808
1820
break ;
1809
1821
case V_REF :
1810
- store_any (
1822
+ symbol = store_any (
1811
1823
program ,
1812
1824
decl -> v .var_decl -> ident -> v .ident -> name
1813
1825
);
@@ -1832,7 +1844,7 @@ void compileDecl(i64_array* program, Decl* decl)
1832
1844
break ;
1833
1845
}
1834
1846
1835
- store_list (
1847
+ symbol = store_list (
1836
1848
program ,
1837
1849
decl -> v .var_decl -> ident -> v .ident -> name ,
1838
1850
len ,
@@ -1855,7 +1867,7 @@ void compileDecl(i64_array* program, Decl* decl)
1855
1867
break ;
1856
1868
}
1857
1869
1858
- store_dict (
1870
+ symbol = store_dict (
1859
1871
program ,
1860
1872
decl -> v .var_decl -> ident -> v .ident -> name ,
1861
1873
len ,
@@ -1866,6 +1878,8 @@ void compileDecl(i64_array* program, Decl* decl)
1866
1878
default :
1867
1879
break ;
1868
1880
}
1881
+
1882
+ symbol -> secondary_type = secondary_type ;
1869
1883
break ;
1870
1884
}
1871
1885
case TimesDo_kind : {
@@ -2310,6 +2324,9 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
2310
2324
break ;
2311
2325
case FieldSpec_kind : {
2312
2326
enum Type type = compileSpec (program , spec -> v .field_spec -> type_spec );
2327
+ enum Type secondary_type = K_ANY ;
2328
+ if (spec -> v .field_spec -> type_spec -> v .type_spec -> sub_type_spec != NULL )
2329
+ secondary_type = spec -> v .field_spec -> type_spec -> v .type_spec -> type ;
2313
2330
2314
2331
Symbol * parameter = NULL ;
2315
2332
union Value value ;
@@ -2337,6 +2354,7 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
2337
2354
default :
2338
2355
break ;
2339
2356
}
2357
+ parameter -> secondary_type = secondary_type ;
2340
2358
2341
2359
parameter -> addr = program -> heap ;
2342
2360
program -> heap += 2 ;
@@ -2345,6 +2363,9 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
2345
2363
}
2346
2364
case OptionalFieldSpec_kind : {
2347
2365
enum Type type = compileSpec (program , spec -> v .optional_field_spec -> type_spec );
2366
+ enum Type secondary_type = K_ANY ;
2367
+ if (spec -> v .optional_field_spec -> type_spec -> v .type_spec -> sub_type_spec != NULL )
2368
+ secondary_type = spec -> v .optional_field_spec -> type_spec -> v .type_spec -> type ;
2348
2369
2349
2370
Symbol * parameter = NULL ;
2350
2371
union Value value ;
@@ -2372,6 +2393,7 @@ unsigned short compileSpec(i64_array* program, Spec* spec)
2372
2393
default :
2373
2394
break ;
2374
2395
}
2396
+ parameter -> secondary_type = secondary_type ;
2375
2397
2376
2398
parameter -> addr = program -> heap ;
2377
2399
program -> heap += 2 ;
@@ -3507,3 +3529,81 @@ void compile_functions(ASTRoot* ast_root, i64_array* program)
3507
3529
popModuleStack ();
3508
3530
}
3509
3531
}
3532
+
3533
+ void strongly_type (Symbol * symbol_x , Symbol * symbol_y , _Function * function , Expr * expr , enum ValueType value_type )
3534
+ {
3535
+ if (expr != NULL ) {
3536
+ if ((symbol_x -> type == K_LIST || symbol_x -> type == K_DICT ) && symbol_x -> secondary_type != K_ANY ) {
3537
+ switch (expr -> kind ) {
3538
+ case CompositeLit_kind : {
3539
+ CompositeLit * composite_lit = expr -> v .composite_lit ;
3540
+ for (unsigned long i = composite_lit -> elts -> expr_count ; 0 < i ; i -- ) {
3541
+ Expr * elt = composite_lit -> elts -> exprs [i - 1 ];
3542
+ switch (elt -> kind ) {
3543
+ case CompositeLit_kind : {
3544
+ if (function != NULL )
3545
+ throw_error (E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER , symbol_x -> name , function -> name );
3546
+ break ;
3547
+ }
3548
+ case BasicLit_kind : {
3549
+ BasicLit * basic_lit = elt -> v .basic_lit ;
3550
+ strongly_type_basic_check (E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER , symbol_x -> name , function -> name , symbol_x -> secondary_type , basic_lit -> value_type );
3551
+ break ;
3552
+ }
3553
+ case KeyValueExpr_kind : {
3554
+ KeyValueExpr * key_value_expr = elt -> v .key_value_expr ;
3555
+ if (key_value_expr -> value -> kind == BasicLit_kind ) {
3556
+ BasicLit * basic_lit = key_value_expr -> value -> v .basic_lit ;
3557
+ strongly_type_basic_check (E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER , symbol_x -> name , function -> name , symbol_x -> secondary_type , basic_lit -> value_type );
3558
+ }
3559
+ break ;
3560
+ }
3561
+ default :
3562
+ break ;
3563
+ }
3564
+ }
3565
+ break ;
3566
+ }
3567
+ case BasicLit_kind : {
3568
+ BasicLit * basic_lit = expr -> v .basic_lit ;
3569
+ strongly_type_basic_check (E_ILLEGAL_ELEMENT_TYPE_FOR_TYPED_LIST , getValueTypeName (basic_lit -> value_type ), symbol_x -> name , symbol_x -> secondary_type , basic_lit -> value_type );
3570
+ break ;
3571
+ }
3572
+ default :
3573
+ break ;
3574
+ }
3575
+ }
3576
+ }
3577
+
3578
+ if (function != NULL && value_type != V_ANY ) {
3579
+ strongly_type_basic_check (E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION_PARAMETER , symbol_x -> name , function -> name , symbol_x -> type , value_type );
3580
+ }
3581
+ }
3582
+
3583
+ void strongly_type_basic_check (unsigned short code , char * str1 , char * str2 , enum Type type , enum ValueType value_type )
3584
+ {
3585
+ switch (type ) {
3586
+ case K_BOOL :
3587
+ if (value_type != V_BOOL )
3588
+ throw_error (code , str1 , str2 );
3589
+ break ;
3590
+ case K_NUMBER :
3591
+ if (value_type != V_INT && value_type != V_FLOAT )
3592
+ throw_error (code , str1 , str2 );
3593
+ break ;
3594
+ case K_STRING :
3595
+ if (value_type != V_STRING )
3596
+ throw_error (code , str1 , str2 );
3597
+ break ;
3598
+ case K_LIST :
3599
+ if (value_type != V_LIST )
3600
+ throw_error (code , str1 , str2 );
3601
+ break ;
3602
+ case K_DICT :
3603
+ if (value_type != V_DICT )
3604
+ throw_error (code , str1 , str2 );
3605
+ break ;
3606
+ default :
3607
+ break ;
3608
+ }
3609
+ }
0 commit comments