public override int GenerateLValue(int loc, IVirtualMachine vm, CheckerInformation info, bool hasToBeLValue = true) { if (IsFuncCall) { throw new IVirtualMachine.InternalError("The result of a function can't be an LValue"); } else { //Write address to the top of the stack if (info.CurrentNamespace != null && info.Namespaces.ContainsKey(info.CurrentNamespace) && info.Namespaces[info.CurrentNamespace].ContainsIdent(Ident)) { IASTStoDecl storage = info.Namespaces[info.CurrentNamespace][Ident]; if (hasToBeLValue) { AssertNotConstant(storage); } if (storage is ASTStoDecl || (storage is ASTParam && ((ASTParam)storage).OptMechmode == MechMode.COPY)) { //Local Identifier or parameter with mechmode COPY vm.LoadRel(loc++, storage.Address); } else if (storage is ASTParam) { //If mechmode is null: default = Mechmode.REF //Load parameter with mechmode REF vm.LoadRel(loc++, storage.Address); //Relative Address to fp vm.Deref(loc++); //Deref to get global Address //With another Deref the value is loaded } else { //Should never happen as long as no new type is added throw new IVirtualMachine.InternalError("Unknown Identifier Type"); } } else if (info.Globals.ContainsIdent(Ident)) { IASTStoDecl storage = info.Globals[Ident]; if (hasToBeLValue) { AssertNotConstant(storage); } vm.IntLoad(loc++, storage.Address); } else { throw new IVirtualMachine.InternalError("Access of undeclared Identifier " + Ident); } return(loc); } }
private void AssertNotConstant(IASTStoDecl sto) { if (sto is ASTStoDecl) { AssertNotConstant((ASTStoDecl)sto); } else if (sto is ASTParam) { AssertNotConstant((ASTParam)sto); } else { //Should never happen as long as no new type is added throw new IVirtualMachine.InternalError("Unknown Identifier Type"); } }