From d3cc49237fa91f50fedaa4453de087d49260d922 Mon Sep 17 00:00:00 2001 From: TheUnlocked <> Date: Sat, 17 Mar 2018 01:35:11 -0700 Subject: [PATCH] Fixed some stuff that didn't work correctly --- FAILang/Builtins/CollectionBuiltinProvider.cs | 33 +++++++++++++++++++ FAILang/Program.cs | 2 +- FAILang/Types/IIndexable.cs | 2 +- .../Unevaluated/BinaryOperatorExpression.cs | 19 +++++++++++ FAILang/Types/Unevaluated/CondExpression.cs | 16 +++++---- .../Types/Unevaluated/FunctionExpression.cs | 3 ++ .../Types/Unevaluated/IndexerExpression.cs | 2 ++ 7 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 FAILang/Builtins/CollectionBuiltinProvider.cs diff --git a/FAILang/Builtins/CollectionBuiltinProvider.cs b/FAILang/Builtins/CollectionBuiltinProvider.cs new file mode 100644 index 0000000..6a290b2 --- /dev/null +++ b/FAILang/Builtins/CollectionBuiltinProvider.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FAILang.Types; + +namespace FAILang.Builtins +{ + class CollectionBuiltinProvider : IBuiltinProvider + { + private static ExternalFunction ValidateType(Func f, Func fail) where T : IType + { + return x => + { + if (x[0] is T t) + return f.Invoke(t); + return fail.Invoke(x[0]); + }; + } + + private static ExternFunction LENGTH = new ExternFunction(ValidateType( + x => new Number(x.Length), + x => new Error("WrongType", $"{x} has no length")), + "c"); + + public (string, ExternFunction)[] GetBuiltins() => new(string, ExternFunction)[] { + ("length", LENGTH) + }; + + public string[] GetReservedNames() => new string[] { + "length" + }; + } +} diff --git a/FAILang/Program.cs b/FAILang/Program.cs index 5a5e409..f3ecc67 100644 --- a/FAILang/Program.cs +++ b/FAILang/Program.cs @@ -14,7 +14,7 @@ class Program { static void Main(string[] args) { - Global.LoadBuiltins(new NumberBuiltinProvider()); + Global.LoadBuiltins(new NumberBuiltinProvider(), new CollectionBuiltinProvider()); Console.InputEncoding = Encoding.Unicode; Console.OutputEncoding = Encoding.Unicode; diff --git a/FAILang/Types/IIndexable.cs b/FAILang/Types/IIndexable.cs index 2035a1f..863f3f7 100644 --- a/FAILang/Types/IIndexable.cs +++ b/FAILang/Types/IIndexable.cs @@ -4,7 +4,7 @@ namespace FAILang.Types { - interface IIndexable + interface IIndexable : IType { int Length { get; } IType IndexRange(int left_b, int right_b); diff --git a/FAILang/Types/Unevaluated/BinaryOperatorExpression.cs b/FAILang/Types/Unevaluated/BinaryOperatorExpression.cs index 987d50f..16e0a93 100644 --- a/FAILang/Types/Unevaluated/BinaryOperatorExpression.cs +++ b/FAILang/Types/Unevaluated/BinaryOperatorExpression.cs @@ -50,7 +50,26 @@ public IType Evaluate(Dictionary lookups) if (left is IUnevaluated || right is IUnevaluated) return new BakedExpression(new BinaryOperatorExpression(op, left, right), lookups); + if (left is Error eLeft) + return eLeft; + if (right is Error eRight) + return eRight; + // Operate + if (op == BinaryOperator.EQUALS) + { + return left.Equals(right) ? MathBool.TRUE : MathBool.FALSE; + } + else if (op == BinaryOperator.NOT_EQUALS) + { + return left.Equals(right) ? MathBool.FALSE : MathBool.TRUE; + } + else + { + if (left == Void.instance || right == Void.instance) + return Void.instance; + } + if (left is IOperable lop && right is IOperable rop) { if (lop.BinaryOperators != null && rop.BinaryOperators != null && lop.BinaryOperators.TryGetValue(op, out var lac) && rop.BinaryOperators.ContainsKey(op)) diff --git a/FAILang/Types/Unevaluated/CondExpression.cs b/FAILang/Types/Unevaluated/CondExpression.cs index 39933db..a109acd 100644 --- a/FAILang/Types/Unevaluated/CondExpression.cs +++ b/FAILang/Types/Unevaluated/CondExpression.cs @@ -25,10 +25,10 @@ public IType Evaluate(Dictionary lookups) { for (int i = 0; i < conds.Length; i++) { - IType t = conds[i]; - if (t is IUnevaluated u) - t = u.Evaluate(lookups); - if (t is Union tu) + IType tCond = conds[i]; + if (tCond is IUnevaluated u) + tCond = u.Evaluate(lookups); + if (tCond is Union tu) { IType[] result = new IType[tu.values.Length]; for (int j = 0; j < result.Length; j++) @@ -39,13 +39,13 @@ public IType Evaluate(Dictionary lookups) } return new Union(result, lookups); } - if (t is IUnevaluated) + if (tCond is IUnevaluated) { var nexpr = new CondExpression(conds.Skip(i).ToArray(), exprs.Skip(i).ToArray(), default_expr); - nexpr.conds[0] = t; + nexpr.conds[0] = tCond; return new BakedExpression(nexpr, lookups); } - if (t == MathBool.TRUE) + if (tCond == MathBool.TRUE) { IType ret = exprs[i]; if (ret is IUnevaluated uexpr) @@ -58,6 +58,8 @@ public IType Evaluate(Dictionary lookups) } return ret; } + if (tCond is Error) + return tCond; } return default_expr is IUnevaluated retd ? retd.Evaluate(lookups) : default_expr; } diff --git a/FAILang/Types/Unevaluated/FunctionExpression.cs b/FAILang/Types/Unevaluated/FunctionExpression.cs index dde51c2..aaa5021 100644 --- a/FAILang/Types/Unevaluated/FunctionExpression.cs +++ b/FAILang/Types/Unevaluated/FunctionExpression.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +using System.Linq; namespace FAILang.Types.Unevaluated { @@ -53,6 +54,8 @@ public IType Evaluate(Dictionary lookups) args.Add(arg); } } + if (args.Any(x => x is IUnevaluated)) + return new BakedExpression(new FunctionExpression(func_expr, args.Select(x => (x, false)).ToArray()), lookups); return f.Evaluate(args.ToArray()); } else if (func is Number n1 && args.Length == 1) diff --git a/FAILang/Types/Unevaluated/IndexerExpression.cs b/FAILang/Types/Unevaluated/IndexerExpression.cs index 1b28da1..3a11d4d 100644 --- a/FAILang/Types/Unevaluated/IndexerExpression.cs +++ b/FAILang/Types/Unevaluated/IndexerExpression.cs @@ -76,6 +76,8 @@ public IType Evaluate(Dictionary lookups) } else { + if (expr is Error) + return expr; return new Error("TypeError", $"The type {expr.TypeName} cannot be indexed"); } }