From 0eac950db6fc862cbe8427242f90bef418a80f34 Mon Sep 17 00:00:00 2001 From: arakov Date: Sun, 24 Mar 2024 20:48:25 +0100 Subject: [PATCH] elt : exception handler (e.g. unresolved reference) --- bin/elt60.es | 3 +- bin/scripts/grammar60.es | 2 +- .../system-dynamic-expressions-summary.html | 39 +++-- doc/api/system-dynamic-expressions.html | 134 ++++++++++++++++++ doc/todo.txt | 5 +- elenasrc3/elenasm/smcommon.h | 2 +- elenasrc3/elenasm/vmparser.cpp | 55 ++++++- elenasrc3/elenavm/elenavmmachine.cpp | 14 +- elenasrc3/elenavm/vmcommon.h | 2 +- elenasrc3/engine/jitlinker.h | 2 + elenasrc3/ide/idecontroller.cpp | 9 ++ elenasrc3/ide/ideversion.h | 2 +- elenasrc3/tools/elt/eltconst.h | 2 +- elenasrc3/tools/elt/vmsession.cpp | 11 +- elenasrc3/tools/elt/vmsession.h | 11 +- elenasrc3/tools/elt/windows/elt.cpp | 48 ++++--- .../system/dynamic/expressions/expressions.l | 31 +++- tests60/sandbox/sandbox.l | 15 +- 18 files changed, 324 insertions(+), 63 deletions(-) diff --git a/bin/elt60.es b/bin/elt60.es index 97c00845f..aa6de97ea 100644 --- a/bin/elt60.es +++ b/bin/elt60.es @@ -4,5 +4,6 @@ #set preloaded preloadedSymbols #postfix " ^ ""safeEval[1]"" " - #start; + + #terminal ]] \ No newline at end of file diff --git a/bin/scripts/grammar60.es b/bin/scripts/grammar60.es index 2475461f7..3cbedd864 100644 --- a/bin/scripts/grammar60.es +++ b/bin/scripts/grammar60.es @@ -344,7 +344,7 @@ #define object ::= <= - system'dynamic'expressions'SymbolExpression ( + system'dynamic'expressions'LazySymbolExpression ( => "reference" "=" ref_quote <= diff --git a/doc/api/system-dynamic-expressions-summary.html b/doc/api/system-dynamic-expressions-summary.html index 72adc633f..74ddef27d 100644 --- a/doc/api/system-dynamic-expressions-summary.html +++ b/doc/api/system-dynamic-expressions-summary.html @@ -242,6 +242,15 @@

+LazySymbolExpression + + +
+public class LazySymbolExpression
+ + + + LoopExpression @@ -249,7 +258,7 @@

public class LoopExpression - + MessageCallExpression @@ -258,7 +267,7 @@

public class MessageCallExpression - + MethodExpression @@ -267,7 +276,7 @@

public class MethodExpression - + MethodParameterList @@ -276,7 +285,7 @@

public class MethodParameterList - + NestedExpression @@ -285,7 +294,7 @@

public class NestedExpression - + NewExpression @@ -294,7 +303,7 @@

public class NewExpression - + ReturnExpression @@ -303,7 +312,7 @@

public class ReturnExpression - + RootExpressionScope @@ -312,7 +321,7 @@

public class RootExpressionScope - + ScopeIdentifier @@ -321,7 +330,7 @@

public class ScopeIdentifier - + SetDynamicPropertyExpression @@ -330,7 +339,7 @@

public class SetDynamicPropertyExpression - + SetPropertyExpression @@ -339,7 +348,7 @@

public class SetPropertyExpression - + SymbolCollection @@ -348,7 +357,7 @@

public class SymbolCollection - + SymbolExpression @@ -357,7 +366,7 @@

public class SymbolExpression - + SymbolInfo @@ -366,7 +375,7 @@

public class SymbolInfo - + VariableByIndexExpression @@ -375,7 +384,7 @@

public class VariableByIndexExpression - + VariableExpression diff --git a/doc/api/system-dynamic-expressions.html b/doc/api/system-dynamic-expressions.html index 17efc0b75..68ac3dda1 100644 --- a/doc/api/system-dynamic-expressions.html +++ b/doc/api/system-dynamic-expressions.html @@ -3263,6 +3263,140 @@

Constructor / Static Method Summary


+ + + +
+
+system'dynamic'expressions'
+

LazySymbolExpression

+
+
+
+
+
+
+public class LazySymbolExpression
+
+
+ + + + + + + + + +
+
diff --git a/doc/todo.txt b/doc/todo.txt index 67dbe883c..001eff33a 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -17,7 +17,10 @@ In development: -------------------------------------- - #617 -------------------------------------- - - work with elt in ide + - elt : exception handler (e.g. unresolved reference) + + - work with elt in ide - invoke a code from the current project + - https://www.reddit.com/r/elena_lang/comments/hyst7t/elena_51_run_elena_code_without_build/ - #621 diff --git a/elenasrc3/elenasm/smcommon.h b/elenasrc3/elenasm/smcommon.h index b2d2d5331..e61e7de7b 100644 --- a/elenasrc3/elenasm/smcommon.h +++ b/elenasrc3/elenasm/smcommon.h @@ -9,7 +9,7 @@ #ifndef RTCOMMON_H #define RTCOMMON_H -#define ELENASM_REVISION_NUMBER 0x000F +#define ELENASM_REVISION_NUMBER 0x0011 namespace elena_lang { diff --git a/elenasrc3/elenasm/vmparser.cpp b/elenasrc3/elenasm/vmparser.cpp index 9c8227dcc..e651cbc57 100644 --- a/elenasrc3/elenasm/vmparser.cpp +++ b/elenasrc3/elenasm/vmparser.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA VM Script Engine // -// (C)2023, by Aleksey Rakov +// (C)2023-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -33,9 +33,11 @@ bool VMTapeParser :: parseDirective(ScriptEngineReaderBase& reader, MemoryDump* break; } else if (reader.compare("#start")) { - writer.write(VM_TERMINAL_CMD); writer.write(VM_INIT_CMD); } + else if (reader.compare("#terminal")) { + writer.write(VM_TERMINAL_CMD); + } else if (reader.compare("#config")) { ScriptBookmark bm = reader.read(); if (bm.state == dfaIdentifier) { @@ -54,6 +56,55 @@ bool VMTapeParser :: parseDirective(ScriptEngineReaderBase& reader, MemoryDump* } else throw SyntaxError("Invalid directive", bm.lineInfo); } + else if (reader.compare("#map")) { + ScriptBookmark bm = reader.read(); + + if (bm.state == dfaQuote) { + writer.write(VM_FORWARD_CMD, reader.lookup(bm)); + } + else { + IdentifierString forward; + if (bm.state == dfaReference) { + forward.append(reader.lookup(bm)); + + bm = reader.read(); + if (!reader.compare("=")) + throw SyntaxError("Invalid #map command", bm.lineInfo); + + bm = reader.read(); + if (bm.state == dfaReference) { + forward.append('='); + forward.append(reader.lookup(bm)); + writer.write(VM_FORWARD_CMD, *forward); + } + throw SyntaxError("Invalid #map command", bm.lineInfo); + } + else throw SyntaxError("Invalid #map command", bm.lineInfo); + } + } + else if (reader.compare("#use")) { + ScriptBookmark bm = reader.read(); + + if (bm.state == dfaQuote) { + writer.write(VM_PACKAGE_CMD, reader.lookup(bm)); + } + else { + IdentifierString package; + package.append(reader.lookup(bm)); + + bm = reader.read(); + if (!reader.compare("=")) + throw SyntaxError("Invalid #use command", bm.lineInfo); + + bm = reader.read(); + if (bm.state == dfaQuote) { + package.append('='); + package.append(reader.lookup(bm)); + writer.write(VM_PACKAGE_CMD, *package); + } + else throw SyntaxError("Invalid #use command", bm.lineInfo); + } + } else if (reader.compare("#postfix")) { ScriptBookmark bm = reader.read(); diff --git a/elenasrc3/elenavm/elenavmmachine.cpp b/elenasrc3/elenavm/elenavmmachine.cpp index cd9761ff2..26f936ac4 100644 --- a/elenasrc3/elenavm/elenavmmachine.cpp +++ b/elenasrc3/elenavm/elenavmmachine.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA VM declaration // -// (C)2021-2023, by Aleksey Rakov +// (C)2021-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -204,6 +204,9 @@ bool ELENAVMMachine :: configurateVM(MemoryReader& reader, SystemEnv* env) _standAloneMode = false; break; case VM_INIT_CMD: + return true; + break; + case VM_ENDOFTAPE_CMD: eop = true; break; case VM_PRELOADED_CMD: @@ -214,7 +217,7 @@ bool ELENAVMMachine :: configurateVM(MemoryReader& reader, SystemEnv* env) } } - return true; + return false; } void ELENAVMMachine :: fillPreloadedSymbols(JITLinker& jitLinker, MemoryWriter& writer, ModuleBase* dummyModule) @@ -410,7 +413,8 @@ addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, ByteArray tapeArray(tape, size); MemoryReader reader(&tapeArray); - stopVM(); + if (_initialized) + stopVM(); JITLinker* jitLinker = nullptr; @@ -433,7 +437,7 @@ addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, else jitLinker->setCompiler(_compiler); } - if (compileVMTape(reader, tapeSymbol, *jitLinker, dummyModule)) { + if (_initialized && compileVMTape(reader, tapeSymbol, *jitLinker, dummyModule)) { void* address = (void*)jitLinker->resolveTemporalByteCode(tapeSymbol, dummyModule); resumeVM(*jitLinker, env, (void*)criricalHandler); @@ -443,7 +447,7 @@ addr_t ELENAVMMachine :: interprete(SystemEnv* env, void* tape, pos_t size, return execute(env, address); } - if (!_standAloneMode) { + if (_initialized && !_standAloneMode) { resumeVM(*jitLinker, env, (void*)criricalHandler); } diff --git a/elenasrc3/elenavm/vmcommon.h b/elenasrc3/elenavm/vmcommon.h index 4995bc1f0..3cc524dc3 100644 --- a/elenasrc3/elenavm/vmcommon.h +++ b/elenasrc3/elenavm/vmcommon.h @@ -9,6 +9,6 @@ #ifndef VMCOMMON_H #define VMCOMMON_H -#define ELENAVM_REVISION_NUMBER 0x0020 +#define ELENAVM_REVISION_NUMBER 0x0021 #endif diff --git a/elenasrc3/engine/jitlinker.h b/elenasrc3/engine/jitlinker.h index 8ff942322..79780334c 100644 --- a/elenasrc3/engine/jitlinker.h +++ b/elenasrc3/engine/jitlinker.h @@ -242,6 +242,8 @@ namespace elena_lang void setCompiler(JITCompilerBase* compiler) { _compiler = compiler; + + _withDebugInfo = _compiler->isWithDebugInfo(); } void complete(JITCompilerBase* compiler, ustr_t superClass); diff --git a/elenasrc3/ide/idecontroller.cpp b/elenasrc3/ide/idecontroller.cpp index ffaed13c1..5908a57f1 100644 --- a/elenasrc3/ide/idecontroller.cpp +++ b/elenasrc3/ide/idecontroller.cpp @@ -350,6 +350,15 @@ bool ProjectController :: startVMConsole(ProjectModel& model) appPath.combine(*model.paths.vmTerminalPath); PathString cmdLine(*model.paths.vmTerminalPath); + cmdLine.append(" \"[[ #use "); + + cmdLine.append(model.getPackage()); + cmdLine.append(_T("=\"\"")); + cmdLine.append(*model.projectPath); + cmdLine.append(_T("\"")); + + cmdLine.append("]]\""); + cmdLine.append(" -i"); return _vmProcess->start(*appPath, *cmdLine, *model.paths.appPath, false); } diff --git a/elenasrc3/ide/ideversion.h b/elenasrc3/ide/ideversion.h index b77982278..2b920d0cc 100644 --- a/elenasrc3/ide/ideversion.h +++ b/elenasrc3/ide/ideversion.h @@ -1,2 +1,2 @@ -#define IDE_REVISION_NUMBER 121 +#define IDE_REVISION_NUMBER 122 diff --git a/elenasrc3/tools/elt/eltconst.h b/elenasrc3/tools/elt/eltconst.h index 04885d9ca..60f5e749b 100644 --- a/elenasrc3/tools/elt/eltconst.h +++ b/elenasrc3/tools/elt/eltconst.h @@ -11,7 +11,7 @@ namespace elena_lang { - #define ELT_REVISION_NUMBER 0x0009 + #define ELT_REVISION_NUMBER 0x000A constexpr auto ELT_GREETING = "ELENA command line VM terminal %d.%d.%d (C)2021-24 by Aleksey Rakov\n"; diff --git a/elenasrc3/tools/elt/vmsession.cpp b/elenasrc3/tools/elt/vmsession.cpp index 19f3bc491..cdfc3e23e 100644 --- a/elenasrc3/tools/elt/vmsession.cpp +++ b/elenasrc3/tools/elt/vmsession.cpp @@ -3,7 +3,7 @@ // // This is a main file containing VM session code // -// (C)2023, by Aleksey Rakov +// (C)2023-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #include "elena.h" @@ -125,6 +125,13 @@ bool VMSession :: executeScript(const char* script) return executeTape(tape); } +void VMSession :: start() +{ + executeScript("[[ #start; ]]"); + + _started = true; +} + bool VMSession :: connect(void* tape) { _env.gc_yg_size = 0x15000; @@ -138,8 +145,6 @@ bool VMSession :: connect(void* tape) return false; } - _started = true; - return true; } diff --git a/elenasrc3/tools/elt/vmsession.h b/elenasrc3/tools/elt/vmsession.h index 78c6322af..375a50331 100644 --- a/elenasrc3/tools/elt/vmsession.h +++ b/elenasrc3/tools/elt/vmsession.h @@ -1,9 +1,9 @@ //--------------------------------------------------------------------------- // E L E N A P r o j e c t: ELENA Tools // -// This is a main file containing VM session code +// This is a main file containing VM session declaration // -// (C)2023, by Aleksey Rakov +// (C)2023-2024, by Aleksey Rakov //--------------------------------------------------------------------------- #ifndef ELTVMSESSION_H @@ -36,16 +36,19 @@ namespace elena_lang void executeCommandLine(const char* line); bool executeTape(void* tape); - bool executeScript(const char* line); - bool executeCommand(const char* line, bool& running); public: void printHelp(); + bool executeScript(const char* line); + bool executeCommand(const char* line, bool& running); + bool loadTemplate(path_t path); bool loadScript(ustr_t pathStr); + void start(); + void run(); VMSession(PresenterBase* presenter); diff --git a/elenasrc3/tools/elt/windows/elt.cpp b/elenasrc3/tools/elt/windows/elt.cpp index 0e49ba9e7..1beb643ca 100644 --- a/elenasrc3/tools/elt/windows/elt.cpp +++ b/elenasrc3/tools/elt/windows/elt.cpp @@ -35,7 +35,16 @@ class ELTPresenter : public WinConsolePresenter } }; -int main() +// default script mode +void startInDefaultMode(VMSession& session) +{ + session.start(); + + session.loadScript(ELT_GRAMMAR_CONFIG); + session.loadScript(ELT_LSCRIPT_CONFIG); +} + +int main(int argc, char* argv[]) { printf(ELT_GREETING, ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, ELT_REVISION_NUMBER); @@ -48,24 +57,29 @@ int main() session.loadTemplate(*commandPath); session.loadScript(ELT_CONFIG); - session.loadScript(ELT_GRAMMAR_CONFIG); - session.loadScript(ELT_LSCRIPT_CONFIG); - session.printHelp(); + // load script passed via command line arguments + if (argc > 1) { + for (int i = 1; i < argc; i++) { + IdentifierString cmd(argv[i]); + + if (argv[i][0] == '-') { + bool running = true; + if (argv[i][1] == 'i') { + startInDefaultMode(session); + } + else session.executeCommand(*cmd, running); + + // check exit command + if (!running) + return 0; + } + else session.executeScript(*cmd); + } + } + else startInDefaultMode(session); - //// load script passed via command line arguments - //if (argc > 1) { - // for (int i = 1; i < argc; i++) { - // if (argv[i][0] == '-') { - // // check exit command - // if (argv[i][1] == 'q') - // return 0; - - // executeCommand(argv[i]); - // } - // else executeScript(argv[i]); - // } - //} + session.printHelp(); session.run(); diff --git a/src60/system/dynamic/expressions/expressions.l b/src60/system/dynamic/expressions/expressions.l index 5586f9a06..2d5e667fc 100644 --- a/src60/system/dynamic/expressions/expressions.l +++ b/src60/system/dynamic/expressions/expressions.l @@ -377,7 +377,7 @@ namespace expressions bool IsOperation = false; - eval() + eval() = symbol; declare(ExpressionScope parentScope) @@ -395,6 +395,35 @@ namespace expressions } } + public class LazySymbolExpression : Expression + { + string symbolReference; + + constructor(string s) + { + symbolReference := s + } + + bool IsOperation = false; + + eval() + = new Symbol(symbolReference); + + declare(ExpressionScope parentScope) + { + } + + saveTo(List list, ExpressionScope scope, int index) + { + list.append(ConstantFunction.load(new Symbol(symbolReference))); + if (index > 0) { + list.append(new SavingFunction(index)); + }; + + scope.reserveStack(1); + } + } + public class FunctionCallExpression : Expression { Message _message; diff --git a/tests60/sandbox/sandbox.l b/tests60/sandbox/sandbox.l index b5f6ae488..eada9d13f 100644 --- a/tests60/sandbox/sandbox.l +++ b/tests60/sandbox/sandbox.l @@ -1,16 +1,13 @@ -public singleton convertor -{ - generic(n) - { - MessageName mssg := __received.MessageName; +import extensions; - ^ mssg(new ExtensionVariable(n, extensions'intConvertOp)) +public singleton MyClassToTest +{ + foo() + { + console.printLine("foo fired!") } } public program() { - var n := convertor.toInt("2"); - - console.writeLine(n) }