Exemple #1
0
        public static EvalResult evaluate_System_Function(SymbolTable symbols, FunCall fun_call)
        {
            var fun_name = fun_call.value.value;
            EvalFunc f = (s,func) => new EvalResult(new Error(fun_call.value.line_num, "Could not match system function!"));

            switch (fun_name)
            {
                case "define": f = add_definition;  break;
                case "+": f = addition;             break;
                case "-": f = subtraction;          break;
                case "*": f = multiplication;       break;
                case "/": f = division;             break;
                case "%": f = mod;                  break;
                case "head": f = head;              break;
                case "tail": f = tail;              break;
                case "++": f = cons;                break;
                case "==": f = equality_test;       break;
                case "not": f = not;                break;
                case "&&": f = logical_and;         break;
                case "||": f = logical_or;          break;
                case "<": f = less_than;            break;
                case ">": f = greater_than;         break;
            }

            return f(symbols, fun_call);
        }
Exemple #2
0
        private static EvalResult gen_function_call_error(FunCall source, int definition_arg_count)
        {
            string fun_name = source.value.value;
            string prefix = (source.args.Count > definition_arg_count) ? "To many " : "To few";
            string error_message = prefix + "arguements to " + fun_name + " it takes " + definition_arg_count.ToString();

            return new EvalResult(new Error(source.value.line_num, fun_name, error_message));
        }
Exemple #3
0
        public static EvalResult evaluate_Identity(SymbolTable symbols, FunCall val)
        {
            // Evaluate symbol
            if (val.value != null && val.value.type == Lexical.Symbol && symbols.ContainsKey(val.value.value))
            {
                return evaluate_Identity(symbols, symbols[val.value.value]);
            }

            else return new EvalResult(new EvalT(symbols, val));
        }
Exemple #4
0
        public static EvalResult cons(SymbolTable symbols, FunCall list)
        {
            return eval_args(symbols, list, "cons", 2, (s, func) =>
            {
                var element = func.args[0];
                var list_arg = func.args[1];

                return new EvalResult(new EvalT(symbols, FunCall.id_list(new List<FunCall> { element, list_arg })));
            });
        }
Exemple #5
0
        public static EvalResult add_definition(SymbolTable symbols, FunCall val)
        {
            var new_fun_name = val.args[0].args.First().value.value;
            var parameters = FunCall.id_list(val.args[0].flattened_args().Skip(1).ToList());
            var fun_body = val.args[1];

            symbols.Add(new_fun_name, FunCall.id_list(new List<FunCall> { parameters, fun_body }));

            return new EvalResult(new EvalT(symbols, new FunCall(Token.symbol("Function Defined"))));
        }
Exemple #6
0
        public static EvalResult not(SymbolTable symbols, FunCall funcall)
        {
            return eval_args(symbols, funcall, "not", 1, (s, func) =>
            {
                var result = func.args[0].value;

                if (result.type != Lexical.Bool) return new EvalResult(new Error(0, "not needs a bool argument!"));
                else if (result.value == "true") return new EvalResult(new EvalT(symbols, FunCall.id_val(Lexical.Bool, 0, "false")));
                else return new EvalResult(new EvalT(symbols, FunCall.id_val(Lexical.Bool, 0, "true")));
            });
        }
Exemple #7
0
        public static EvalResult binary_typeCheck(SymbolTable symbols, FunCall funcall, string funcName, EvalFunc f)
        {
            var left = funcall.args[0].value;
            var right = funcall.args[1].value;

            Func<Token, bool> isNumber = token => token.type == Lexical.Int || token.type == Lexical.Float;
            bool areNumbers = isNumber(left) && isNumber(right);

            if (areNumbers || left.type == right.type) return f(symbols, funcall);
            else return new EvalResult(new Error(0, "Non-matching types for " + funcName));
        }
Exemple #8
0
        public static EvalResult list_access(SymbolTable symbols, FunCall list, Func<SymbolTable, FunCall, EvalResult> list_op, string func_name)
        {
            return eval_args(symbols, list, func_name, 2, (s, func) =>
            {
                var list_arg = func.args.First();

                if (!isList(list_arg)) return new EvalResult(new Error(0, func_name + " must be called on a list!"));

                return list_op(symbols, list_arg);
            });
        }
Exemple #9
0
        public static EvalResult less_than(SymbolTable symbols, FunCall funcall)
        {
            return eval_args(symbols, funcall, "<", 2, (_s, _func) =>
            {
                return binary_typeCheck(symbols, funcall, "<", (s, func) =>
                {
                    var left = Convert.ToDouble(func.args[0].value.value);
                    var right = Convert.ToDouble(func.args[1].value.value);

                    var result = (left < right).ToString();

                    return new EvalResult(new EvalT(s, FunCall.id_val(Lexical.Bool, 0, result)));
                });
            });
        }
Exemple #10
0
        public static EvalResult logical_or(SymbolTable symbols, FunCall funcall)
        {
            return eval_args(symbols, funcall, "||", 2, (_s, _func) =>
            {
                return binary_typeCheck(_s, _func, Lexical.Bool, Lexical.Bool, "||", (s, func) =>
                {
                    var left = func.args[0].value;
                    var right = func.args[1].value;
                    string result = "";
                    if (left.value == "true" || right.value == "true") result = "true";
                    else result = "false";

                    return new EvalResult(new EvalT(s, FunCall.id_val(Lexical.Bool, 0, result)));
                });
            });
        }
Exemple #11
0
        public static EvalResult math_op(SymbolTable symbols, FunCall fun, Func<Token, double, double> math_op, string func_name)
       {
            var args = fun.args.Select(a => evaluate_FunCall(symbols, a));
            Func<FunCall, bool> isNumerical = arg => arg.value.type == Lexical.Int || arg.value.type == Lexical.Float;
            double sum = 0;
            bool seen_first_val = false;

            foreach (var arg in fun.args)
            {
                FunCall val = arg;

                if (!isNumerical(val) && symbols.ContainsKey(arg.value.value))
                    val = symbols[arg.value.value];

                if (isNumerical(val))
                {
                    if (!seen_first_val)
                    {
                        sum = math_identity(val.value);
                        seen_first_val = true;
                    }
                    else sum = math_op(val.value, sum);
                }
                else
                {
                    string prefix = (val.value.type == Lexical.Symbol) ? "Undefined Symbol" : "Non-numerical value ";
                    string message = prefix + val.ToString() + " given to " + func_name;
                    var error = new Error(fun.value.line_num, val.ToString(), message);
                    return new EvalResult(error);
                }
            }

            var isInt = Regex.IsMatch(sum.ToString(), @".*\.0+");
            Token result = isInt ? new Token(Lexical.Int, 0, ((int)sum).ToString()) : new Token(Lexical.Float, 0, sum.ToString());
            return new EvalResult(new EvalT(symbols, new FunCall(result)));
       }
Exemple #12
0
 public static EvalResult subtraction(SymbolTable symbols, FunCall fun)
 {
     return math_op(symbols, fun, perform_subtraction, "-");
 }
Exemple #13
0
 public static EvalResult evaluate_FunCall(SymbolTable symbols, FunCall fun)
 {
     bool function = fun.value != null && fun.value.type == Lexical.Symbol;
     
     if (function) return evaluate_Function(symbols, fun);
     else return evaluate_Identity(symbols, fun);
 }
Exemple #14
0
        public static EvalResult evaluate_Function(SymbolTable symbols, FunCall fun_call)
        {
            var fun_name = fun_call.value.value;

            if (reserved_symbols.Contains(fun_name)) return evaluate_System_Function(symbols, fun_call);
            else if (symbols.ContainsKey(fun_name)) return evaluate_User_Function(symbols, fun_call);

            return null;
        }
Exemple #15
0
        public static EvalResult evaluate_User_Function(SymbolTable symbols, FunCall fun_call)
        {
            FunCall definition = symbols[fun_call.value.value];
            FunCall funArgs = definition.args[0];
            FunCall funBody = definition.args[1];

            if (fun_call.args.Count != funArgs.args.Count)
                return gen_function_call_error(fun_call, funArgs.args.Count);

            var arg_pairs = funArgs.args.Zip(fun_call.args, (a, b) => new Tuple<FunCall, FunCall>(a, b));

            // Bind args and add to symbol table
            foreach (var arg_pair in arg_pairs) symbols.Add(arg_pair.Item1.value.value, arg_pair.Item2);

            return evaluate_FunCall(symbols, funBody);
        }
Exemple #16
0
        public static EvalResult eval_args(SymbolTable symbols, FunCall funcall, string funcName, int numArgs, EvalFunc f)
        {
            var evaled_args = funcall.args.Select(i => evaluate_FunCall(symbols, i)).ToList();

            if (evaled_args.Count() > numArgs) return new EvalResult(new Error(0, "Too many arguments to " + funcName + "!"));
            if (evaled_args.Count() < numArgs) return new EvalResult(new Error(0, "Too few arguments to " + funcName + "!"));

            foreach(var result in evaled_args)
                if (result.left == null) return new EvalResult(result.right);

            var results = FunCall.id_list(evaled_args.Select(a => a.left.Item2).ToList());

            return f(symbols, results);
        }
Exemple #17
0
 public static List<FunCall> id(FunCall value)
 {
     return new List<FunCall> { value };
 }
Exemple #18
0
 public static EvalResult mod(SymbolTable symbols, FunCall fun)
 {
     return math_op(symbols, fun, perform_mod, "%");
 }
Exemple #19
0
 public static EvalResult get_head(SymbolTable symbols, FunCall result_list)
 {
     return new EvalResult(new EvalT(symbols, result_list.args_head()));
 }
Exemple #20
0
 public static EvalResult division(SymbolTable symbols, FunCall fun)
 {
     return math_op(symbols, fun, perform_division, "/");
 }
Exemple #21
0
 public static EvalResult head(SymbolTable symbols, FunCall list)
 {
     return list_access(symbols, list, get_head, "head");
 }
Exemple #22
0
 public static bool isList(FunCall list)
 {
     return list.value == null;
 }
Exemple #23
0
        public static EvalResult equality_test(SymbolTable symbols, FunCall funcall)
        {
            return eval_args(symbols, funcall, "==", 2, (s, func) =>
            {
                var left = func.args[0];
                var right = func.args[1];

                string result = "";

                switch (left.value.type)
                {
                    case Lexical.Bool: result = (left.value.value == right.value.value).ToString(); break;
                    case Lexical.Int:
                    case Lexical.Float: result = (Convert.ToDouble(left.value.value) == Convert.ToDouble(right.value.value)).ToString(); break;
                    case Lexical.String: result = (left.value.value == right.value.value).ToString(); break;
                    default: return new EvalResult(new Error(0, "Unknown lex type passed to equality_test"));
                }

                return new EvalResult(new EvalT(symbols, FunCall.id_val(Lexical.Bool, 0, result)));
            });
        }
Exemple #24
0
 public static EvalResult tail(SymbolTable symbols, FunCall list)
 {
     return list_access(symbols, list, get_tail, "tail");
 }
Exemple #25
0
 public static EvalResult multiplication(SymbolTable symbols, FunCall fun)
 {
     return math_op(symbols, fun, perform_multiplication, "*");
 }
Exemple #26
0
        public static EvalResult get_tail(SymbolTable symbols, FunCall result_list)
        {
            var new_list = FunCall.id_list(result_list.args_tail());

            return new EvalResult(new EvalT(symbols, new_list));
        }
Exemple #27
0
 public static EvalResult addition(SymbolTable symbols, FunCall fun)
 {
     return math_op(symbols, fun, perform_additon, "+");
 }