@@ -28,6 +28,8 @@ class BackendUXN : CompilerBackend {
2828 uint currentLoop;
2929
3030 this () {
31+ addrSize = 2 ;
32+
3133 types ~= Type(" u8" , 1 );
3234 types ~= Type(" i8" , 1 );
3335 types ~= Type(" u16" , 2 );
@@ -182,43 +184,62 @@ class BackendUXN : CompilerBackend {
182184 }
183185
184186 void PushVariableValue (
185- Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false
187+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
188+ bool deref = false
186189 ) {
187190 if (size == 0 ) {
188- size = var.type.size;
189- }
190- if (var.type.isStruct && ! member) {
191- Error(node.error, " Can't push value of struct" );
191+ size = var.type.Size();
192192 }
193193
194- if (var.offset == 0 ) {
195- output ~= " .vsp LDZ2\n " ;
194+ if (deref) {
195+ if (var.offset == 0 ) {
196+ output ~= " .vsp LDZ2\n " ;
197+ }
198+ else {
199+ output ~= format(" .vsp LDZ2 #%.4x ADD2\n " , var.offset);
200+ }
201+
202+ output ~= " LDA2\n " ;
203+
204+ if (offset != 0 ) {
205+ output ~= format(" #%.4x ADD2\n " , offset);
206+ }
196207 }
197208 else {
198- output ~= format(" .vsp LDZ2 #%.4x ADD2\n " , var.offset);
209+ if (var.offset + offset == 0 ) {
210+ output ~= " .vsp LDZ2\n " ;
211+ }
212+ else {
213+ output ~= format(" .vsp LDZ2 #%.4x ADD2\n " , var.offset + offset);
214+ }
199215 }
200216
201- switch (var.type. size) {
217+ switch (size) {
202218 case 1 : output ~= " LDA NIP\n " ; break ;
203219 case 2 : output ~= " LDA2\n " ; break ;
204220 default : Error (node.error, " Bad variable type size" );
205221 }
206222 }
207223
208224 void PushGlobalValue (
209- Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false
225+ Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false ,
226+ bool deref = false
210227 ) {
211228 if (size == 0 ) {
212- size = var.type.size ;
229+ size = var.type.Size() ;
213230 }
214231
215232 output ~= format(" ;global_%s\n " , var.name.Sanitise());
216233
217- if (var.type.isStruct && ! member) {
218- Error(node.error, " Can't push value of struct" );
234+ if (deref) {
235+ output ~= " LDA2\n " ;
236+ }
237+
238+ if (offset != 0 ) {
239+ output ~= format(" #%.4x ADD2\n " , offset);
219240 }
220241
221- switch (var.type. size) {
242+ switch (size) {
222243 case 1 : output ~= " LDA NIP\n " ; break ;
223244 case 2 : output ~= " LDA2\n " ; break ;
224245 default : Error (node.error, " Bad variable type size" );
@@ -287,20 +308,40 @@ class BackendUXN : CompilerBackend {
287308 }
288309 }
289310 else if (VariableExists(node.name)) {
311+ auto var = GetVariable(node.name);
312+
313+ if (var.type.isStruct && ! var.type.ptr) {
314+ Error(node.error, " Can't push value of structures" );
315+ }
316+
290317 PushVariableValue(node, GetVariable (node.name));
291318 }
292319 else if (GlobalExists(node.name)) {
320+ auto var = GetGlobal(node.name);
321+
322+ if (var.type.isStruct && ! var.type.ptr) {
323+ Error(node.error, " Can't push value of structures" );
324+ }
325+
293326 PushGlobalValue(node, GetGlobal (node.name));
294327 }
295328 else if (IsStructMember(node.name)) {
296329 string name = node.name[0 .. node.name.countUntil(" ." )];
297330 auto structVar = GetStructVariable(node, node.name);
298331
299332 if (GlobalExists(name)) {
300- PushGlobalValue(node, GetGlobal (name), structVar.size, structVar.offset, true );
333+ auto var = GetGlobal(name);
334+
335+ PushGlobalValue(
336+ node, var, structVar.size, structVar.offset, true , var.type.ptr
337+ );
301338 }
302339 else if (VariableExists(name)) {
303- PushVariableValue(node, GetVariable (name), structVar.size, structVar.offset, true );
340+ auto var = GetVariable(name);
341+
342+ PushVariableValue(
343+ node, var, structVar.size, structVar.offset, true , var.type.ptr
344+ );
304345 }
305346 }
306347 else if (node.name in consts) {
@@ -852,50 +893,50 @@ class BackendUXN : CompilerBackend {
852893 }
853894
854895 void SetVariable (
855- Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false
896+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
897+ bool deref = false
856898 ) {
857899 if (size == 0 ) {
858- size = var.type.size;
859- }
860- if (var.type.isStruct && ! member) {
861- Error(node.error, " Can't set struct value" );
900+ size = var.type.Size();
862901 }
863902
864- if (var.offset == 0 ) {
865- switch (var.type.size) {
866- case 1 : output ~= " NIP .vsp LDZ2 STA\n " ; break ;
867- case 2 : output ~= " .vsp LDZ2 STA2\n " ; break ;
868- default : Error (node.error, " Bad variable type size" );
869- }
903+ string where = " .vsp LDZ2" ;
904+
905+ if (var.offset != 0 ) {
906+ where ~= format(" #%.4x ADD2" , var.offset);
870907 }
871- else {
872- switch (var.type.size) {
873- case 1 : {
874- output ~= format(" NIP .vsp LDZ2 #%.4X ADD2 STA\n " , var.offset);
875- break ;
876- }
877- case 2 : {
878- output ~= format(" .vsp LDZ2 #%.4X ADD2 STA2\n " , var.offset);
879- break ;
880- }
881- default : Error (node.error, " Bad variable type size" );
882- }
908+ if (deref) {
909+ where ~= " LDA2" ;
910+ }
911+ if (offset != 0 ) {
912+ where ~= format(" #%.4x ADD2" , offset);
913+ }
914+
915+ switch (size) {
916+ case 1 : output ~= format(" NIP %s STA\n " , where); break ;
917+ case 2 : output ~= format(" %s STA2\n " , where); break ;
918+ default : Error (node.error, " Bad variable type size" );
883919 }
884920 }
885921
886922 void SetGlobal (
887- Node node, Global global, size_t size = 0 , size_t offset = 0 , bool member = false
923+ Node node, Global global, size_t size = 0 , size_t offset = 0 , bool member = false ,
924+ bool deref = false
888925 ) {
889926 if (size == 0 ) {
890- size = global.type.size;
891- }
892- if (global.type.isStruct && ! member) {
893- Error(node.error, " Can't set struct value" );
927+ size = global.type.Size();
894928 }
895929
896930 string symbol = format(" global_%s" , global.name.Sanitise());
897931
898- switch (global.type.size) {
932+ if (deref) {
933+ symbol ~= format(" LDA2" );
934+ }
935+ if (offset != 0 ) {
936+ symbol ~= format(" #%.4x ADD2" , offset);
937+ }
938+
939+ switch (size) {
899940 case 1 : output ~= format(" NIP ;%s STA\n " , symbol); break ;
900941 case 2 : output ~= format(" ;%s STA2\n " , symbol); break ;
901942 default : Error (node.error, " Bad variable type size" );
@@ -904,20 +945,40 @@ class BackendUXN : CompilerBackend {
904945
905946 override void CompileSet (SetNode node) {
906947 if (VariableExists(node.var)) {
907- SetVariable(node, GetVariable (node.var));
948+ auto var = GetVariable(node.var);
949+
950+ if (var.type.isStruct && ! var.type.ptr) {
951+ Error(node.error, " Can't set struct value" );
952+ }
953+
954+ SetVariable(node, var);
908955 }
909956 else if (GlobalExists(node.var)) {
957+ auto var = GetGlobal(node.var);
958+
959+ if (var.type.isStruct && ! var.type.ptr) {
960+ Error(node.error, " Can't set struct value" );
961+ }
962+
910963 SetGlobal(node, GetGlobal (node.var));
911964 }
912965 else if (IsStructMember(node.var)) {
913966 string name = node.var[0 .. node.var.countUntil(" ." )];
914967 auto structVar = GetStructVariable(node, node.var);
915968
916969 if (VariableExists(name)) {
917- SetVariable(node, GetVariable (name), structVar.size, structVar.offset, true );
970+ auto var = GetVariable(name);
971+
972+ SetVariable(
973+ node, var, structVar.size, structVar.offset, true , var.type.ptr
974+ );
918975 }
919976 else if (GlobalExists(name)) {
920- SetGlobal(node, GetGlobal (name), structVar.size, structVar.offset, true );
977+ auto var = GetGlobal(name);
978+
979+ SetGlobal(
980+ node, var, structVar.size, structVar.offset, true , var.type.ptr
981+ );
921982 }
922983 }
923984 else {
0 commit comments