예제 #1
0
        // create a function value
        // BUG: a persistent function must not reference a non-persistent global
        public AstValue Funval(AstType rettype, IList <AstField> arguments, AstBodyStatement body)
        {
            var code = Code(body.Statement as AstValue, Headingof(arguments), "λ", false, body.AccumCount, body.HasWin);

            return(new AstFunval {
                Value = code, DataType = DataTypeCode.Get(code.DataType, code.Lookup)
            });
        }
예제 #2
0
        // finalise function definition, from basic definition previously created
        // set or check return type
        // null body just defines type
        // Note: null arguments means argless (lazy) rather than deffun
        // BUG: a persistent function must not reference a non-persistent global
        public AstStatement Deffun(string ident, AstType rettype, IList <AstField> arguments, AstBodyStatement body)
        {
            var op       = FindDefFunc(ident);
            var callinfo = op.CallInfo;

            if (callinfo.ReturnType == DataTypes.Unknown)
            {
                callinfo.ReturnType = body.DataType;
            }
            else if (callinfo.ReturnType != body.DataType)
            {
                Parser.ParseError($"{ident} return type mismatch");
            }
            if (op.DataType == DataTypes.Unknown)
            {
                if (arguments == null)
                {
                    op.DataType = callinfo.ReturnType;
                }
            }
            else if (op.DataType != callinfo.ReturnType)
            {
                Parser.ParseError("body does not match declared type");
            }

            // assume top overload is the one being defined
            //op.callinfo.ReturnType = op.DataType;
            callinfo.AccumCount = body.AccumCount;
            callinfo.HasWin     = body.HasWin;
            // symbol is foldable if all overloads are foldable
            // FIX: put this test where it's used
            var foldable = (callinfo.NumArgs == 2 && arguments[0].DataType == callinfo.ReturnType && arguments[1].DataType == callinfo.ReturnType) &&
                           (callinfo.OverLoad == null || op.IsFoldable);

            if (foldable && !op.IsFoldable)
            {
                op.Foldable = FoldableFlags.ANY;
            }
            Symbols.AddCatalog(op);

            // assemble node
            var code = Code(body.Statement as AstValue, Headingof(arguments), callinfo.Name, true, body.AccumCount, body.HasWin);

            return(GenFunCall(FindFunc(SymNames.Defer), Args(code)));
        }