using Island.StandardLib; using System.Collections.Generic; namespace EXTS { public abstract class Statement { internal EXTSEngine engine; public Statement() => engine = EXTSEngine.CompilingEngine; public abstract EValue Eval(); } public class StatementList : Statement { internal static StatementList runningStatement; internal List statements; Dictionary val; internal StatementList parentVarlst; internal bool stop; public StatementList() => val = new Dictionary(); public EValue this[string name] { get { if (val.ContainsKey(name)) return val[name]; StatementList lst = this; while (lst.parentVarlst != null) { lst = lst.parentVarlst; if (lst.val.ContainsKey(name)) return lst.val[name]; } return new EValue(); } set { if (val.ContainsKey(name)) { val[name] = value; return; } StatementList lst = this; while (lst.parentVarlst != null) { lst = lst.parentVarlst; if (lst.val.ContainsKey(name)) { lst.val[name] = value; return; } } val.Add(name, value); } } public StatementList(params Statement[] sms) { statements = new List(sms); } public void AddStatement(Statement statement) { statements.Add(statement); } public virtual bool BeforeEval() { return true; } public override EValue Eval() { stop = false; runningStatement = this; val = new Dictionary(); val.Set("return", new EValue()); if (!BeforeEval()) return new EValue(new EString(engine.funcptrs.PushRandom((FuncStatement)this))); for (int i = 0; i < statements.Count; i++) { statements[i].Eval(); if (stop) break; } EValue ret = val.Get("return", new EValue()); val.Clear(); return ret; } } public class SetValStatement : Statement { StatementList env; string name; Statement value; public SetValStatement(StatementList elist, string valname, Statement val) { env = elist; name = valname; value = val; } public override EValue Eval() { EValue val = value.Eval(); env[name] = val; return val; } } public class GetValStatement : Statement { StatementList env; string name; public GetValStatement(StatementList elist, string valname) { env = elist; name = valname; } public override EValue Eval() => env[name]; } public class ImmediateStatement : Statement { EValue val; public ImmediateStatement(string immval) { if (float.TryParse(immval, out float f)) val = new EValue(new ENumber(f)); else val = new EValue(new EString(immval)); } public override EValue Eval() => val; } public class ReturnStatement : Statement { public override EValue Eval() { StatementList.runningStatement.stop = true; return new EValue(); } } public class FuncStatement : StatementList { internal string name; internal EValue[] parameters; public bool runfunc = true; public FuncStatement(params Statement[] statements) : base(statements) { } public override bool BeforeEval() { if (parameters != null) { for (int i = 0; i < parameters.Length; i++) this["pmt" + i] = parameters[i]; } parameters = null; return runfunc; } public EValue Eval(EValue[] pmts) { parameters = pmts; return base.Eval(); } } public class BodyFuncStatement : StatementList { internal KeyValuePair[] parameters; public BodyFuncStatement(params Statement[] statements) : base(statements) { } public override bool BeforeEval() { if (parameters != null) { for (int i = 0; i < parameters.Length; i++) this[parameters[i].Key] = parameters[i].Value; } parameters = null; return true; } public EValue Eval(params KeyValuePair[] pmts) { parameters = pmts; return base.Eval(); } } public class CallFuncStatement : Statement { string func; Statement[] pmts; public CallFuncStatement(string funcName, params Statement[] parameters) { for (int i = 0; i < parameters.Length; i++) parameters[i].engine = engine; func = funcName; pmts = parameters; } public override EValue Eval() => engine.RunFuncBase(func, pmts.Do((p) => p.Eval())); } }