public override IType VisitDef([NotNull] FAILangParser.DefContext context) { var name = context.name().GetText(); var update = context.update; var exp = context.expression(); if (Global.reservedNames.Contains(name)) { return(new Error("DefineFailed", $"{name} is a reserved name.")); } if (update == null && Global.globalVariables.ContainsKey(name)) { return(new Error("DefineFailed", "The update keyword is required to change a function or variable.")); } bool memoize = context.memoize != null; // `update memo name` pattern if (exp == null && memoize) { if (!Global.globalVariables.ContainsKey(name)) { return(new Error("UpdateFailed", $"{name} is not defined")); } if (Global.globalVariables.TryGetValue(name, out var val) && val is Function func) { if (func.memoize) { func.memos.Clear(); } else { func.memoize = true; } } else { return(new Error("UpdateFailed", $"{name} is not a function")); } } else if (context.fparams() != null) { IType expr = VisitExpression(exp); Function f = new Function(context.fparams().param().Select(x => x.GetText()).ToArray(), expr, memoize: memoize, elipsis: context.fparams().elipsis != null); Global.globalVariables[name] = f; } else { var v = Global.Evaluate(VisitExpression(exp)); if (v is Error) { return(v); } Global.globalVariables[name] = v; } return(null); }
public new (string name, IType value) VisitDef([NotNull] FAILangParser.DefContext context) { var name = context.name().GetText(); var exp = context.expression(); bool memoize = context.memoize != null; if (context.fparams() != null) { IType expr = VisitExpression(exp); var f = new UnevaluatedFunction(context.fparams().param().Select(x => x.GetText()).ToArray(), expr, memoize: memoize, elipsis: context.fparams().elipsis != null); return(name, f); } else { var v = VisitExpression(exp); if (v is Error) { return(null, v); } return(name, v); } }