123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using NTERA.Core;
- using NTERA.EmuEra.Game.EraEmu.Content;
- using NTERA.Engine.Compiler;
- namespace NTERA.Engine.Runtime
- {
- public class EraRuntime : IScriptEngine
- {
- public IExecutionProvider ExecutionProvider { get; }
- public IConsole Console { get; protected set; }
- public Stack<ExecutionSet> ExecutionStack { get; } = new Stack<ExecutionSet>();
- public EraRuntime(IExecutionProvider executionProvider)
- {
- ExecutionProvider = executionProvider;
- }
- public bool Initialize(IConsole console)
- {
- Console = console;
- return true;
- }
- public void Start()
- {
- Console.PrintSystemLine("EraJIT x64 0.0.0.0");
- Console.PrintSystemLine("");
- try
- {
- Call(ExecutionProvider.DefinedProcedures.First(x => x.Name == "SYSTEM_TITLE"));
- }
- catch (Exception ex)
- {
- Console.PrintSystemLine($"Unhandled exception: {ex.Message}");
- Console.PrintSystemLine("Stack trace:");
- foreach (var stackMember in ExecutionStack)
- Console.PrintSystemLine($" - @{stackMember.SelfDefinition.Name} ({stackMember.SelfDefinition.Position} > {stackMember.SelfDefinition.Filename})");
- throw;
- }
- System.Threading.Thread.Sleep(-1);
- }
- public void Call(FunctionDefinition function)
- {
- var executionContents = ExecutionProvider.GetExecutionNodes(function);
- var localVariables = new VariableDictionary();
- foreach (var variable in function.Variables)
- localVariables[variable.Name] = variable.CalculatedValue;
- var globalVariables = new VariableDictionary();
- foreach (var variable in BaseDefinitions.DefaultGlobalVariables)
- globalVariables[variable.Name] = variable.CalculatedValue;
- var executionSet = new ExecutionSet
- {
- Nodes = executionContents.ToList(),
- SelfDefinition = function,
- GlobalVariables = globalVariables,
- LocalVariables = localVariables
- };
- ExecutionStack.Push(executionSet);
- ExecuteSet(executionSet);
- ExecutionStack.Pop();
- }
- public void ExecuteSet(ExecutionSet set)
- {
- for (; set.Position < set.Nodes.Count; set.Position++)
- {
- ExecutionNode node = set.Nodes[set.Position];
- ExecuteNode(set, node);
- }
- }
- public void ExecuteNode(ExecutionSet set, ExecutionNode node)
- {
- switch (node.Type)
- {
- case "statement":
- string statement = node.Metadata["name"];
- if (!Base.Keywords.StaticKeywords.TryGetValue(statement, out var keywordAction))
- throw new Exception($"Unknown statement: '{statement}'");
- keywordAction(this, set, node);
- break;
- case "assignment":
- string variableName = node["variable"].Metadata["name"];
- if (set.LocalVariables.ContainsKey(variableName))
- set.LocalVariables[variableName] = ComputeExpression(set, node["value"].SubNodes.Single());
- else if (set.GlobalVariables.ContainsKey(variableName))
- set.GlobalVariables[variableName] = ComputeExpression(set, node["value"].SubNodes.Single());
- else
- throw new Exception($"Unknown variable: '{variableName}'");
- break;
- default:
- throw new Exception($"Unknown node type: '{node.Type}'");
- }
- }
- public Value ComputeExpression(ExecutionSet set, ExecutionNode expressionNode)
- {
- switch (expressionNode.Type)
- {
- case "constant":
- ValueType type = (ValueType)Enum.Parse(typeof(ValueType), expressionNode.Metadata["type"]);
- string strValue = expressionNode.Metadata["value"];
- return type == ValueType.String ? (Value)strValue : (Value)double.Parse(strValue);
- default:
- throw new Exception($"Unknown expression type: '{expressionNode.Type}'");
- }
- }
- public void InputString(string input)
- {
- throw new NotImplementedException();
- }
- public void InputInteger(long input)
- {
- throw new NotImplementedException();
- }
- public void InputSystemInteger(long input)
- {
- throw new NotImplementedException();
- }
- public CroppedImage GetImage(string name)
- {
- throw new NotImplementedException();
- }
- }
- }
|