diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index ffb6fd3367..e780fdd31c 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -7,6 +7,7 @@ #include "generator.hpp" #include "scanner.hpp" #include "errorhandler.hpp" +#include "locals.hpp" namespace Compiler { @@ -212,6 +213,19 @@ namespace Compiler Scanner& scanner) { mFirst = false; + + if (mNextOperand) + { + char type = mLocals.getType (name); + + if (type!=' ') + { + Generator::fetchLocal (mCode, type, mLocals.getIndex (name)); + mNextOperand = false; + mOperands.push_back (type=='f' ? 'f' : 'l'); + return true; + } + } return Parser::parseName (name, loc, scanner); } diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index ddbae874a4..9a07820db1 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -160,6 +160,21 @@ namespace { code.push_back (segment3 (0, buttons)); } + + void opFetchLocalShort (Compiler::Generator::CodeContainer& code) + { + code.push_back (segment5 (21)); + } + + void opFetchLocalLong (Compiler::Generator::CodeContainer& code) + { + code.push_back (segment5 (22)); + } + + void opFetchLocalFloat (Compiler::Generator::CodeContainer& code) + { + code.push_back (segment5 (23)); + } } namespace Compiler @@ -347,6 +362,33 @@ namespace Compiler opPushInt (code, index); opMessageBox (code, buttons); } + + void fetchLocal (CodeContainer& code, char localType, int localIndex) + { + opPushInt (code, localIndex); + + switch (localType) + { + case 'f': + + opFetchLocalFloat (code); + break; + + case 's': + + opFetchLocalShort (code); + break; + + case 'l': + + opFetchLocalLong (code); + break; + + default: + + assert (0); + } + } } } diff --git a/components/compiler/generator.hpp b/components/compiler/generator.hpp index 2dd81711e2..9a5b568ca1 100644 --- a/components/compiler/generator.hpp +++ b/components/compiler/generator.hpp @@ -39,6 +39,8 @@ namespace Compiler void message (CodeContainer& code, Literals& literals, const std::string& message, int buttons); + + void fetchLocal (CodeContainer& code, char localType, int localIndex); } } diff --git a/components/interpreter/docs/vmformat.txt b/components/interpreter/docs/vmformat.txt index c5bc133f70..ffa906b90d 100644 --- a/components/interpreter/docs/vmformat.txt +++ b/components/interpreter/docs/vmformat.txt @@ -77,6 +77,9 @@ op 17: convert stack[1] from integer to float op 18: convert stack[1] from float to integer op 19: take square root of stack[0] (float) op 20: return -opcodes 21-33554431 unused +op 21: replace stack[0] with local short stack[0] +op 22: replace stack[0] with local long stack[0] +op 23: replace stack[0] with local float stack[0] +opcodes 24-33554431 unused opcodes 33554432-67108863 reserved for extensions diff --git a/components/interpreter/installopcodes.cpp b/components/interpreter/installopcodes.cpp index 5836967ed1..63d9e6c3fc 100644 --- a/components/interpreter/installopcodes.cpp +++ b/components/interpreter/installopcodes.cpp @@ -21,13 +21,16 @@ namespace Interpreter interpreter.installSegment5 (17, new OpIntToFloat1); interpreter.installSegment5 (18, new OpFloatToInt1); - // local variables + // local variables & literals interpreter.installSegment5 (0, new OpStoreLocalShort); interpreter.installSegment5 (1, new OpStoreLocalLong); interpreter.installSegment5 (2, new OpStoreLocalFloat); interpreter.installSegment5 (4, new OpFetchIntLiteral); interpreter.installSegment5 (5, new OpFetchFloatLiteral); - + interpreter.installSegment5 (21, new OpFetchLocalShort); + interpreter.installSegment5 (22, new OpFetchLocalLong); + interpreter.installSegment5 (23, new OpFetchLocalFloat); + // math interpreter.installSegment5 (9, new OpAddInt); interpreter.installSegment5 (10, new OpAddInt); diff --git a/components/interpreter/localopcodes.hpp b/components/interpreter/localopcodes.hpp index d156359679..4be661d87f 100644 --- a/components/interpreter/localopcodes.hpp +++ b/components/interpreter/localopcodes.hpp @@ -76,6 +76,42 @@ namespace Interpreter runtime[0] = *reinterpret_cast (&floatValue); } }; + + class OpFetchLocalShort : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + int index = runtime[0]; + int value = runtime.getContext().getLocalShort (index); + runtime[0] = *reinterpret_cast (&value); + } + }; + + class OpFetchLocalLong : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + int index = runtime[0]; + int value = runtime.getContext().getLocalLong (index); + runtime[0] = *reinterpret_cast (&value); + } + }; + + class OpFetchLocalFloat : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + int index = runtime[0]; + float value = runtime.getContext().getLocalFloat (index); + runtime[0] = *reinterpret_cast (&value); + } + }; } #endif