@@ -47,6 +47,8 @@ class BackendLua : CompilerBackend {
4747 ulong arrayStack = 524287 ;
4848
4949 this () {
50+ addrSize = 1 ;
51+
5052 // built in integer types
5153 types ~= Type(" addr" , 1 );
5254 types ~= Type(" size" , 1 );
@@ -168,42 +170,45 @@ class BackendLua : CompilerBackend {
168170
169171 void PushVariableValue (
170172 Node node, Variable var, size_t size = 0 , size_t offset = 0 ,
171- bool member = false
173+ bool member = false , bool deref = false
172174 ) {
173175 if (size == 0 ) {
174- size = var.type.size;
175- }
176-
177- if (var.type.isStruct && ! member) {
178- Error(node.error, " Can't push value of struct" );
176+ size = var.type.Size();
179177 }
180178
181179 if (size != 1 ) {
182- Error(node.error, " Bad variable type size" );
180+ Error(node.error, " Bad variable type size (%d) " , size );
183181 }
184182
185- output ~= format(" mem[dsp] = mem[vsp + %d]\n " , var.offset);
183+ if (deref) {
184+ output ~= format(" mem[dsp] = mem[mem[vsp + %d] + %d]\n " , var.offset, offset);
185+ }
186+ else {
187+ output ~= format(" mem[dsp] = mem[vsp + %d]\n " , var.offset + offset);
188+ }
186189 output ~= " dsp = dsp + 1\n " ;
187190 }
188191
189192 void PushGlobalValue (
190- Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false
193+ Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false ,
194+ bool deref = false
191195 ) {
192196 if (size == 0 ) {
193- size = var.type.size ;
197+ size = var.type.Size() ;
194198 }
195199
196200 auto extra = cast (GlobalExtra* ) var.extra;
197201
198- if (var.type.isStruct && ! member ) {
199- Error(node.error, " Can't push value of struct " );
202+ if (size != 1 ) {
203+ Error(node.error, " Bad variable type size (%d) " , size );
200204 }
201205
202- if (var.type.size != 1 ) {
203- Error(node.error, " Bad variable type size" );
206+ if (deref) {
207+ output ~= format(" mem[dsp] = mem[mem[%d] + %d]\n " , extra.addr, offset);
208+ }
209+ else {
210+ output ~= format(" mem[dsp] = mem[%d]\n " , extra.addr + offset);
204211 }
205-
206- output ~= format(" mem[dsp] = mem[%d]\n " , extra.addr);
207212 output ~= " dsp = dsp + 1\n " ;
208213 }
209214
@@ -245,20 +250,40 @@ class BackendLua : CompilerBackend {
245250 }
246251 }
247252 else if (VariableExists(node.name)) {
253+ auto var = GetVariable(node.name);
254+
255+ if (var.type.isStruct && ! var.type.ptr) {
256+ Error(node.error, " Can't push value of structures" );
257+ }
258+
248259 PushVariableValue(node, GetVariable (node.name));
249260 }
250261 else if (GlobalExists(node.name)) {
262+ auto var = GetGlobal(node.name);
263+
264+ if (var.type.isStruct && ! var.type.ptr) {
265+ Error(node.error, " Can't push value of structures" );
266+ }
267+
251268 PushGlobalValue(node, GetGlobal (node.name));
252269 }
253270 else if (IsStructMember(node.name)) {
254271 string name = node.name[0 .. node.name.countUntil(" ." )];
255272 auto structVar = GetStructVariable(node, node.name);
256273
257274 if (GlobalExists(name)) {
258- PushGlobalValue(node, GetGlobal (name), structVar.size, structVar.offset, true );
275+ auto var = GetGlobal(name);
276+
277+ PushGlobalValue(
278+ node, var, structVar.size, structVar.offset, true , var.type.ptr
279+ );
259280 }
260281 else if (VariableExists(name)) {
261- PushVariableValue(node, GetVariable (name), structVar.size, structVar.offset, true );
282+ auto var = GetVariable(name);
283+
284+ PushVariableValue(
285+ node, var, structVar.size, structVar.offset, true , var.type.ptr
286+ );
262287 }
263288 }
264289 else if (node.name in consts) {
@@ -821,47 +846,82 @@ class BackendLua : CompilerBackend {
821846
822847 void SetGlobal (
823848 Node node, Global global, size_t size = 0 , size_t offset = 0 ,
824- bool member = false
849+ bool member = false , bool deref = false
825850 ) {
826851 if (size == 0 ) {
827- size = global.type.size ;
852+ size = global.type.Size() ;
828853 }
829854
830- auto extra = cast (GlobalExtra* ) global.extra;
831-
832- if (global.type.isStruct && ! member) {
833- Error(node.error, " Can't set struct value" );
855+ if (size != 1 ) {
856+ Error(node.error, " Bad variable type size" );
834857 }
835858
836- output ~= format(" mem[%d] = cal_pop()\n " , extra.addr);
859+ auto extra = cast (GlobalExtra* ) global.extra;
860+
861+ if (deref) {
862+ output ~= format(" mem[mem[%d] + %d] = cal_pop()\n " , extra.addr, offset);
863+ }
864+ else {
865+ output ~= format(" mem[%d] = cal_pop()\n " , extra.addr + offset);
866+ }
837867 }
838868
839869 void SetVariable (
840- Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false
870+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
871+ bool deref = false
841872 ) {
842- if (var.type.isStruct && ! member) {
843- Error(node.error, " Can't set struct value" );
873+ if (size == 0 ) {
874+ size = var.type.Size();
875+ }
876+
877+ if (size != 1 ) {
878+ Error(node.error, " Bad variable type size" );
844879 }
845880
846- output ~= format(" mem[vsp + %d] = cal_pop()\n " , var.offset);
881+ if (deref) {
882+ output ~= format(" mem[mem[vsp + %d] + %d] = cal_pop()\n " , var.offset, offset);
883+ }
884+ else {
885+ output ~= format(" mem[vsp + %d] = cal_pop()\n " , var.offset + offset);
886+ }
847887 }
848888
849889 override void CompileSet (SetNode node) {
850890 if (VariableExists(node.var)) {
851- SetVariable(node, GetVariable (node.var));
891+ auto var = GetVariable(node.var);
892+
893+ if (var.type.isStruct && ! var.type.ptr) {
894+ Error(node.error, " Can't set struct value" );
895+ }
896+
897+ SetVariable(node, var);
852898 }
853899 else if (GlobalExists(node.var)) {
900+ auto var = GetGlobal(node.var);
901+
902+ if (var.type.isStruct && ! var.type.ptr) {
903+ Error(node.error, " Can't set struct value" );
904+ }
905+
854906 SetGlobal(node, GetGlobal (node.var));
855907 }
856908 else if (IsStructMember(node.var)) {
857909 string name = node.var[0 .. node.var.countUntil(" ." )];
858910 auto structVar = GetStructVariable(node, node.var);
859911
860912 if (VariableExists(name)) {
861- SetVariable(node, GetVariable (name), structVar.size, structVar.offset, true );
913+ auto var = GetVariable(name);
914+
915+ SetVariable(
916+ node, var, structVar.size, structVar.offset, true , var.type.ptr
917+ );
862918 }
863919 else if (GlobalExists(name)) {
864- SetGlobal(node, GetGlobal (name), structVar.size, structVar.offset, true );
920+ auto var = GetGlobal(name);
921+
922+ SetGlobal(
923+ node, var, structVar.size, structVar.offset, true , var.type.ptr
924+ );
865925 }
866926 }
867927 else {
0 commit comments