diff --git a/Core/EVIL.Grammar/Parsing/Expressions/Parser.Indexing.cs b/Core/EVIL.Grammar/Parsing/Expressions/Parser.IndexerExpression.cs
similarity index 94%
rename from Core/EVIL.Grammar/Parsing/Expressions/Parser.Indexing.cs
rename to Core/EVIL.Grammar/Parsing/Expressions/Parser.IndexerExpression.cs
index 57a38680..9fed47f6 100644
--- a/Core/EVIL.Grammar/Parsing/Expressions/Parser.Indexing.cs
+++ b/Core/EVIL.Grammar/Parsing/Expressions/Parser.IndexerExpression.cs
@@ -7,7 +7,7 @@ namespace EVIL.Grammar.Parsing
{
public partial class Parser
{
- private IndexerExpression Indexing(Expression indexable)
+ private IndexerExpression IndexerExpression(Expression indexable)
{
int line, col;
Expression indexer;
diff --git a/Core/EVIL.Grammar/Parsing/Expressions/Parser.FunctionCall.cs b/Core/EVIL.Grammar/Parsing/Expressions/Parser.InvocationExpression.cs
similarity index 89%
rename from Core/EVIL.Grammar/Parsing/Expressions/Parser.FunctionCall.cs
rename to Core/EVIL.Grammar/Parsing/Expressions/Parser.InvocationExpression.cs
index 686fa264..e47e1603 100644
--- a/Core/EVIL.Grammar/Parsing/Expressions/Parser.FunctionCall.cs
+++ b/Core/EVIL.Grammar/Parsing/Expressions/Parser.InvocationExpression.cs
@@ -6,7 +6,7 @@ namespace EVIL.Grammar.Parsing
{
public partial class Parser
{
- private InvocationExpression FunctionCall(Expression callee)
+ private InvocationExpression InvocationExpression(Expression callee)
{
var (line, col) = (_lexer.State.Line, _lexer.State.Column);
diff --git a/Core/EVIL.Grammar/Parsing/Expressions/Parser.PostfixExpression.cs b/Core/EVIL.Grammar/Parsing/Expressions/Parser.PostfixExpression.cs
index 1116435d..7210f060 100644
--- a/Core/EVIL.Grammar/Parsing/Expressions/Parser.PostfixExpression.cs
+++ b/Core/EVIL.Grammar/Parsing/Expressions/Parser.PostfixExpression.cs
@@ -45,11 +45,11 @@ private Expression PostfixExpression()
if (token.Type == TokenType.LParenthesis)
{
- node = FunctionCall(node);
+ node = InvocationExpression(node);
}
else if (token.Type == TokenType.LBracket || token.Type == TokenType.Dot)
{
- node = Indexing(node);
+ node = IndexerExpression(node);
}
else if (token.Type == TokenType.DoubleColon)
{
diff --git a/Core/EVIL.Grammar/Parsing/Statements/Parser.EachLoop.cs b/Core/EVIL.Grammar/Parsing/Statements/Parser.EachLoop.cs
index ec2d0c02..f8f12dc5 100644
--- a/Core/EVIL.Grammar/Parsing/Statements/Parser.EachLoop.cs
+++ b/Core/EVIL.Grammar/Parsing/Statements/Parser.EachLoop.cs
@@ -14,7 +14,7 @@ private EachStatement EachLoop()
if (CurrentToken == Token.Val)
{
throw new ParserException(
- "Each-loop variables must be `rw'.",
+ "Each-loop variables must be 'rw'.",
(_lexer.State.Line, _lexer.State.Column)
);
}
diff --git a/FrontEnd/EVIL.evil/EvmFrontEnd.cs b/FrontEnd/EVIL.evil/EvmFrontEnd.cs
index 44704849..fb9ef84d 100644
--- a/FrontEnd/EVIL.evil/EvmFrontEnd.cs
+++ b/FrontEnd/EVIL.evil/EvmFrontEnd.cs
@@ -142,6 +142,8 @@ public async Task Run(string[] args)
RegisterAllModules();
SetStandardGlobals(scriptPath);
+ _runtime.RegisterBuiltInFunctions();
+
_vm.Scheduler.SetDefaultCrashHandler(CrashHandler);
_vm.MainFiber.SetCrashHandler(CrashHandler);
_vm.Start();
diff --git a/VirtualMachine/Ceres.Runtime/Ceres.Runtime.csproj b/VirtualMachine/Ceres.Runtime/Ceres.Runtime.csproj
index e6a28559..c8753ed9 100644
--- a/VirtualMachine/Ceres.Runtime/Ceres.Runtime.csproj
+++ b/VirtualMachine/Ceres.Runtime/Ceres.Runtime.csproj
@@ -13,4 +13,11 @@
+
+
+
+
+ Never
+
+
diff --git a/VirtualMachine/Ceres.Runtime/EvilRuntime.cs b/VirtualMachine/Ceres.Runtime/EvilRuntime.cs
index 05bdb1d1..ebd44961 100644
--- a/VirtualMachine/Ceres.Runtime/EvilRuntime.cs
+++ b/VirtualMachine/Ceres.Runtime/EvilRuntime.cs
@@ -1,28 +1,65 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
using Ceres.ExecutionEngine;
using Ceres.ExecutionEngine.Collections;
+using Ceres.ExecutionEngine.Diagnostics;
using Ceres.ExecutionEngine.TypeSystem;
using Ceres.Runtime.Extensions;
using Ceres.Runtime.Modules;
+using Ceres.TranslationEngine;
namespace Ceres.Runtime
{
public sealed class EvilRuntime
{
private readonly CeresVM _vm;
+ private readonly Compiler _compiler;
private Table Global => _vm.Global;
public EvilRuntime(CeresVM vm)
{
_vm = vm;
+ _compiler = new Compiler();
+ }
+
+ public List RegisterBuiltInFunctions()
+ {
+ var scriptNames = Assembly
+ .GetExecutingAssembly()
+ .GetManifestResourceNames()
+ .Where(x => x.StartsWith("Ceres.Runtime.ScriptBuiltins"));
+
+ var list = new List();
+
+ foreach (var scriptName in scriptNames)
+ {
+ using var stream = Assembly
+ .GetExecutingAssembly()
+ .GetManifestResourceStream(scriptName)!;
+
+ using var streamReader = new StreamReader(stream);
+
+ var text = streamReader.ReadToEnd();
+ var root = _compiler.Compile(text, $"builtin::{scriptName}");
+
+ foreach (var (name, id) in root.NamedSubChunkLookup)
+ {
+ list.Add(root.SubChunks[id]);
+ _vm.Global.Set(name, root.SubChunks[id]);
+ }
+ }
+
+ return list;
}
public List RegisterBuiltInModules()
{
var modules = new List();
-
+
modules.Add(RegisterModule(out _));
modules.Add(RegisterModule(out _));
modules.Add(RegisterModule(out _));
diff --git a/VirtualMachine/Ceres.Runtime/ScriptBuiltins/dofile.vil b/VirtualMachine/Ceres.Runtime/ScriptBuiltins/dofile.vil
new file mode 100644
index 00000000..0f4acd50
--- /dev/null
+++ b/VirtualMachine/Ceres.Runtime/ScriptBuiltins/dofile.vil
@@ -0,0 +1,14 @@
+fn dofile(path) {
+ if (!fs.file.exists(path)) -> core.error(
+ "Couldn't find a file at '" + @path + "'."
+ );
+
+ val source = fs.file.get_text(path);
+ val result = evil.compile(source, path);
+
+ if (!result || !result.success) -> core.error(
+ "Failed to compile the file '" + @path + "': " + @result.message
+ );
+
+ ret result.chunk();
+}
\ No newline at end of file
diff --git a/VirtualMachine/Ceres/TranslationEngine/Compiler.cs b/VirtualMachine/Ceres/TranslationEngine/Compiler.cs
index e689adb1..125a0d73 100644
--- a/VirtualMachine/Ceres/TranslationEngine/Compiler.cs
+++ b/VirtualMachine/Ceres/TranslationEngine/Compiler.cs
@@ -9,6 +9,8 @@
using EVIL.Grammar.AST.Base;
using EVIL.Grammar.AST.Constants;
using EVIL.Grammar.AST.Miscellaneous;
+using EVIL.Grammar.AST.Statements;
+using EVIL.Grammar.AST.Statements.TopLevel;
using EVIL.Grammar.Parsing;
using EVIL.Grammar.Traversal;
using EVIL.Lexical;
@@ -110,10 +112,10 @@ public Chunk Compile(ProgramNode programNode, string fileName = "")
CurrentFileName = fileName;
_closedScopes.Clear();
_chunks.Clear();
-
+
return InRootChunkDo(() => Visit(programNode));
}
-
+
private Chunk InRootChunkDo(Action action)
{
_rootChunk = new Chunk("!_root_chunk");
@@ -194,13 +196,14 @@ public override void Visit(AstNode node)
node = expression.Reduce();
}
- base.Visit(node);
-
- if (_chunks.Any())
+ if (_blockDescent > 0 || _chunks.Count == 1)
{
- var location = LocationStack.Pop();
- Chunk.DebugDatabase.AddDebugRecord(location.Line, Chunk.CodeGenerator.LastOpCodeIP);
+ Chunk.DebugDatabase.AddDebugRecord(Line, Chunk.CodeGenerator.LastOpCodeIP);
}
+
+ base.Visit(node);
+
+ Chunk.DebugDatabase.AddDebugRecord(Line, Chunk.CodeGenerator.LastOpCodeIP);
}
public void RegisterAttributeProcessor(string attributeName, AttributeProcessor processor)