Beispiel #1
0
        public override void Compile()
        {
            int argCount = es.Length - 1;

            if (es.Length < 1)
            {
                LoadErrorValue(ErrorValue.argCountError);
            }
            else if (es[0] is CGTextConst)
            {
                String  name    = (es[0] as CGTextConst).value.value;
                SdfInfo sdfInfo = SdfManager.GetInfo(name);
                if (sdfInfo == null)
                {
                    LoadErrorValue(ErrorValue.nameError);
                }
                else if (argCount != 0 && argCount != sdfInfo.arity)
                {
                    LoadErrorValue(ErrorValue.argCountError);
                }
                else
                {
                    ilg.Emit(OpCodes.Ldc_I4, sdfInfo.index);
                    CompileToValueArray(argCount, 1, es);
                    ilg.Emit(OpCodes.Call, FunctionValue.makeMethod);
                }
            }
            else
            {
                es[0].Compile();
                CheckType(FunctionValue.type,
                          new Gen(delegate {
                    CompileToValueArray(argCount, 1, es);
                    ilg.Emit(OpCodes.Call, FunctionValue.furtherApplyMethod);
                }),
                          GenLoadErrorValue(ErrorValue.argTypeError));
            }
        }
Beispiel #2
0
        public static CGExpr Make(String name, CGExpr[] es)
        {
            name = name.ToUpper();
            // This switch should agree with the function table in Functions.cs
            switch (name)
            {
            case "+":
                return(new CGArithmetic2(OpCodes.Add, name, es));

            case "*":
                return(new CGArithmetic2(OpCodes.Mul, name, es));

            case "-":
                return(new CGArithmetic2(OpCodes.Sub, name, es));

            case "/":
                return(new CGArithmetic2(OpCodes.Div, name, es));

            case "=":
                return(CGEqual.Make(es));

            case "<>":
                return(CGNotEqual.Make(es));

            case ">":
                return(new CGGreaterThan(es));

            case "<=":
                return(new CGLessThanOrEqual(es));

            case "<":
                return(new CGLessThan(es));

            case ">=":
                return(new CGGreaterThanOrEqual(es));

            // Non-strict, or other special treatment
            case "AND":
                return(new CGAnd(es));

            case "APPLY":
                return(new CGApply(es));

            case "CHOOSE":
                return(new CGChoose(es));

            case "CLOSURE":
                return(new CGClosure(es));

            case "ERR":
                return(new CGError(es));

            case "EXTERN":
                return(new CGExtern(es));

            case "IF":
                return(new CGIf(es));

            case "NA":
                if (es.Length == 0)
                {
                    return(new CGError(ErrorValue.naError));
                }
                else
                {
                    return(new CGError(ErrorValue.argCountError));
                }

            case "NEG":
                return(new CGNeg(es));

            case "NOT":
                return(new CGNot(es));

            case "OR":
                return(new CGOr(es));

            case "PI":
                if (es.Length == 0)
                {
                    return(new CGNumberConst(NumberValue.PI));
                }
                else
                {
                    return(new CGError(ErrorValue.argCountError));
                }

            case "VOLATILIZE":
                if (es.Length == 1)
                {
                    return(es[0]);
                }
                else
                {
                    return(new CGError(ErrorValue.argCountError));
                }

            default:
                // The general case for most built-in functions with unspecific argument types
                FunctionInfo functionInfo;
                if (FunctionInfo.Find(name, out functionInfo))
                {
                    return(new CGFunctionCall(functionInfo, es));
                }
                else                           // May be a sheet-defined function
                {
                    SdfInfo sdfInfo = SdfManager.GetInfo(name);
                    if (sdfInfo != null)
                    {
                        return(new CGSdfCall(sdfInfo, es));
                    }
                    else
                    {
                        return(new CGError(ErrorValue.nameError));
                    }
                }
            }
        }