@@ -311,6 +311,9 @@ fn (mut c Amd64) cmp_var_reg(var Var, reg Register, config VarConfig) {
311
311
// TODO
312
312
// g.cmp()
313
313
}
314
+ ExternVar {
315
+ c.cmp_var_reg (var_object as ExternVar , reg, config)
316
+ }
314
317
}
315
318
}
316
319
LocalVar {
@@ -330,6 +333,9 @@ fn (mut c Amd64) cmp_var_reg(var Var, reg Register, config VarConfig) {
330
333
GlobalVar {
331
334
// TODO
332
335
}
336
+ ExternVar {
337
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
338
+ }
333
339
}
334
340
}
335
341
@@ -348,6 +354,9 @@ fn (mut c Amd64) cmp_var(var Var, val i32, config VarConfig) {
348
354
// TODO
349
355
// g.cmp()
350
356
}
357
+ ExternVar {
358
+ c.cmp_var (var_object as ExternVar , val, config)
359
+ }
351
360
}
352
361
}
353
362
LocalVar {
@@ -367,6 +376,9 @@ fn (mut c Amd64) cmp_var(var Var, val i32, config VarConfig) {
367
376
GlobalVar {
368
377
// TODO
369
378
}
379
+ ExternVar {
380
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
381
+ }
370
382
}
371
383
}
372
384
@@ -386,6 +398,9 @@ fn (mut c Amd64) dec_var(var Var, config VarConfig) {
386
398
// TODO
387
399
// g.dec()
388
400
}
401
+ ExternVar {
402
+ c.dec_var (var_object as ExternVar , config)
403
+ }
389
404
}
390
405
}
391
406
LocalVar {
@@ -405,6 +420,9 @@ fn (mut c Amd64) dec_var(var Var, config VarConfig) {
405
420
GlobalVar {
406
421
// TODO
407
422
}
423
+ ExternVar {
424
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
425
+ }
408
426
}
409
427
}
410
428
@@ -425,6 +443,9 @@ fn (mut c Amd64) inc_var(var Var, config VarConfig) {
425
443
// TODO
426
444
// g.inc()
427
445
}
446
+ ExternVar {
447
+ c.inc_var (var_object as ExternVar , config)
448
+ }
428
449
}
429
450
}
430
451
LocalVar {
@@ -468,6 +489,9 @@ fn (mut c Amd64) inc_var(var Var, config VarConfig) {
468
489
c.g.n_error ('${@LOCATION} Global variables incrementation is not supported yet' )
469
490
// TODO
470
491
}
492
+ ExternVar {
493
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
494
+ }
471
495
}
472
496
}
473
497
@@ -662,6 +686,9 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
662
686
// TODO
663
687
c.g.n_error ('${@LOCATION} unsupported Ident Register' )
664
688
}
689
+ ExternVar {
690
+ c.mov_reg_to_var (var_object as ExternVar , reg, config)
691
+ }
665
692
}
666
693
}
667
694
LocalVar {
@@ -743,6 +770,9 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
743
770
// TODO
744
771
c.g.n_error ('${@LOCATION} Unsupported GlobalVar' )
745
772
}
773
+ ExternVar {
774
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
775
+ }
746
776
}
747
777
}
748
778
@@ -760,6 +790,9 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer i32, config VarConfig) {
760
790
Register {
761
791
// TODO
762
792
}
793
+ ExternVar {
794
+ c.mov_int_to_var (var_object as ExternVar , integer, config)
795
+ }
763
796
}
764
797
}
765
798
LocalVar {
@@ -822,6 +855,9 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer i32, config VarConfig) {
822
855
GlobalVar {
823
856
// TODO
824
857
}
858
+ ExternVar {
859
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
860
+ }
825
861
}
826
862
}
827
863
@@ -868,6 +904,9 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
868
904
Register {
869
905
// TODO
870
906
}
907
+ ExternVar {
908
+ c.mov_var_to_reg (reg, var_object as ExternVar , config)
909
+ }
871
910
}
872
911
}
873
912
LocalVar {
@@ -933,6 +972,9 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
933
972
GlobalVar {
934
973
c.g.n_error ('${@LOCATION} Unsupported GlobalVar' )
935
974
}
975
+ ExternVar {
976
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
977
+ }
936
978
}
937
979
}
938
980
@@ -2077,19 +2119,34 @@ fn (mut c Amd64) assign_var(var IdentVar, raw_type ast.Type) {
2077
2119
size := c.g.get_type_size (typ)
2078
2120
if typ.is_pure_float () {
2079
2121
match var {
2080
- LocalVar { c.mov_ssereg_to_var (var as LocalVar , .xmm0 ) }
2081
- GlobalVar { c.mov_ssereg_to_var (var as GlobalVar , .xmm0 ) }
2122
+ LocalVar {
2123
+ c.mov_ssereg_to_var (var as LocalVar , .xmm0 )
2124
+ }
2125
+ GlobalVar {
2126
+ c.mov_ssereg_to_var (var as GlobalVar , .xmm0 )
2127
+ }
2082
2128
// Amd64Register { c.g.mov_ssereg(var as Amd64Register, .xmm0) }
2083
- else {}
2129
+ else {
2130
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
2131
+ }
2084
2132
}
2085
2133
} else if info is ast.Struct && ! typ.is_any_kind_of_pointer ()
2086
2134
&& ! raw_type.is_any_kind_of_pointer () {
2087
2135
c.assign_struct_var (var, typ, size)
2088
2136
} else if int (size) in [1 , 2 , 4 , 8 ] {
2089
2137
match var {
2090
- LocalVar { c.mov_reg_to_var (var as LocalVar , Amd64 Register.rax) }
2091
- GlobalVar { c.mov_reg_to_var (var as GlobalVar , Amd64 Register.rax) }
2092
- Register { c.mov_reg (var as Amd64Register , Amd64 Register.rax) }
2138
+ LocalVar {
2139
+ c.mov_reg_to_var (var as LocalVar , Amd64 Register.rax)
2140
+ }
2141
+ GlobalVar {
2142
+ c.mov_reg_to_var (var as GlobalVar , Amd64 Register.rax)
2143
+ }
2144
+ Register {
2145
+ c.mov_reg (var as Amd64Register , Amd64 Register.rax)
2146
+ }
2147
+ ExternVar {
2148
+ c.mov_reg_to_var (var as ExternVar , Amd64 Register.rax)
2149
+ }
2093
2150
}
2094
2151
} else {
2095
2152
c.g.n_error ('${@LOCATION} error assigning type ${typ} with size ${size} : ${info} ' )
@@ -2121,6 +2178,12 @@ fn (mut c Amd64) assign_ident_int_lit(node ast.AssignStmt, i i32, int_lit ast.In
2121
2178
c.div_reg (.rax, .rdx)
2122
2179
c.mov_reg_to_var (left, Amd64 Register.rax)
2123
2180
}
2181
+ .mod_assign {
2182
+ c.mov_var_to_reg (Amd64 Register.rax, left)
2183
+ c.mov64 (Amd64 Register.rdx, i64 (int_lit.val.int ()))
2184
+ c.mod_reg (.rax, .rdx)
2185
+ c.mov_reg_to_var (left, Amd64 Register.rax)
2186
+ }
2124
2187
.decl_assign {
2125
2188
c.allocate_var (left.name, 8 , i64 (int_lit.val.int ()))
2126
2189
}
@@ -2241,11 +2304,19 @@ fn (mut c Amd64) assign_ident_right_expr(node ast.AssignStmt, i i32, right ast.E
2241
2304
val := enum_info.fields[right.val] or {
2242
2305
c.g.n_error ('${@LOCATION} enum field not found ${right.val} ' )
2243
2306
}
2244
- if node.op == .decl_assign {
2245
- c.allocate_var (ident.name, enum_info.size, val)
2246
- } else {
2247
- c.mov64 (Amd64 Register.rax, val)
2248
- c.mov_reg_to_var (ident, Amd64 Register.rax)
2307
+ match val {
2308
+ Number {
2309
+ if node.op == .decl_assign {
2310
+ c.allocate_var (ident.name, enum_info.size, val)
2311
+ } else {
2312
+ c.mov64 (Amd64 Register.rax, val)
2313
+ c.mov_reg_to_var (ident, Amd64 Register.rax)
2314
+ }
2315
+ }
2316
+ ast.Expr {
2317
+ c.g.expr (val)
2318
+ c.mov_reg_to_var (ident, Amd64 Register.rax)
2319
+ }
2249
2320
}
2250
2321
}
2251
2322
ast.FloatLiteral {
@@ -2777,14 +2848,35 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
2777
2848
c.pop (.rdx) // effective address of left expr
2778
2849
c.gen_type_promotion (node.right_types[0 ], var_type)
2779
2850
2851
+ size := match c.g.get_type_size (var_type) {
2852
+ 1 { Size._8 }
2853
+ 2 { Size._16 }
2854
+ 4 { Size._32 }
2855
+ else { Size._64 }
2856
+ }
2780
2857
match node.op {
2781
2858
.decl_assign, .assign {
2782
- c.mov_store (.rdx, .rax, match c.g.get_type_size (var_type) {
2783
- 1 { ._8 }
2784
- 2 { ._16 }
2785
- 4 { ._32 }
2786
- else { ._64 }
2787
- })
2859
+ c.mov_store (.rdx, .rax, size)
2860
+ }
2861
+ .plus_assign {
2862
+ c.mov_deref (Amd64 Register.rcx, Amd64 Register.rdx, var_type)
2863
+ c.add_reg (.rax, .rcx)
2864
+ c.mov_store (.rdx, .rax, size)
2865
+ }
2866
+ .minus_assign {
2867
+ c.mov_deref (Amd64 Register.rcx, Amd64 Register.rdx, var_type)
2868
+ c.sub_reg (.rax, .rcx)
2869
+ c.mov_store (.rdx, .rax, size)
2870
+ }
2871
+ .and_assign {
2872
+ c.mov_deref (Amd64 Register.rcx, Amd64 Register.rdx, var_type)
2873
+ c.bitand_reg (.rax, .rcx)
2874
+ c.mov_store (.rdx, .rax, size)
2875
+ }
2876
+ .mod_assign {
2877
+ c.mov_deref (Amd64 Register.rcx, Amd64 Register.rdx, var_type)
2878
+ c.mod_reg (.rax, .rcx)
2879
+ c.mov_store (.rdx, .rax, size)
2788
2880
}
2789
2881
else {
2790
2882
c.g.n_error ('${@LOCATION} Unsupported assign instruction (${node.op} )' )
@@ -3676,6 +3768,9 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
3676
3768
// TODO
3677
3769
// c.g.cmp()
3678
3770
}
3771
+ ExternVar {
3772
+ c.init_struct (var_object as ExternVar , init)
3773
+ }
3679
3774
}
3680
3775
}
3681
3776
LocalVar {
@@ -3718,6 +3813,9 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
3718
3813
GlobalVar {
3719
3814
c.g.n_error ('${@LOCATION} GlobalVar not implemented for ast.StructInit' )
3720
3815
}
3816
+ ExternVar {
3817
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
3818
+ }
3721
3819
}
3722
3820
}
3723
3821
@@ -3766,6 +3864,9 @@ fn (mut c Amd64) init_array(var Var, node ast.ArrayInit) {
3766
3864
// TODO
3767
3865
// c.g.cmp()
3768
3866
}
3867
+ ExternVar {
3868
+ c.init_array (var_object as ExternVar , node)
3869
+ }
3769
3870
}
3770
3871
}
3771
3872
LocalVar {
@@ -3779,6 +3880,9 @@ fn (mut c Amd64) init_array(var Var, node ast.ArrayInit) {
3779
3880
GlobalVar {
3780
3881
c.g.n_error ('${@LOCATION} GlobalVar not implemented for ast.ArrayInit' )
3781
3882
}
3883
+ ExternVar {
3884
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
3885
+ }
3782
3886
}
3783
3887
}
3784
3888
@@ -4075,6 +4179,9 @@ fn (mut c Amd64) mov_ssereg_to_var(var Var, reg Amd64SSERegister, config VarConf
4075
4179
c.mov_ssereg_to_var (var_object as GlobalVar , reg, config)
4076
4180
}
4077
4181
Register {}
4182
+ ExternVar {
4183
+ c.mov_ssereg_to_var (var_object as ExternVar , reg, config)
4184
+ }
4078
4185
}
4079
4186
}
4080
4187
LocalVar {
@@ -4100,6 +4207,9 @@ fn (mut c Amd64) mov_ssereg_to_var(var Var, reg Amd64SSERegister, config VarConf
4100
4207
GlobalVar {
4101
4208
// TODO
4102
4209
}
4210
+ ExternVar {
4211
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
4212
+ }
4103
4213
}
4104
4214
}
4105
4215
@@ -4119,6 +4229,9 @@ fn (mut c Amd64) mov_var_to_ssereg(reg Amd64SSERegister, var Var, config VarConf
4119
4229
c.mov_var_to_ssereg (reg, var_object as GlobalVar , config)
4120
4230
}
4121
4231
Register {}
4232
+ ExternVar {
4233
+ c.mov_var_to_ssereg (reg, var_object as ExternVar , config)
4234
+ }
4122
4235
}
4123
4236
}
4124
4237
LocalVar {
@@ -4144,6 +4257,9 @@ fn (mut c Amd64) mov_var_to_ssereg(reg Amd64SSERegister, var Var, config VarConf
4144
4257
GlobalVar {
4145
4258
// TODO
4146
4259
}
4260
+ ExternVar {
4261
+ c.g.n_error ('${@LOCATION} unsupported var type ${var} ' )
4262
+ }
4147
4263
}
4148
4264
}
4149
4265
0 commit comments