Esempio n. 1
0
        public void Visit(NodeFnDecl fn)
        {
            var self = AddFunction(module, fn.Name, TypeConverter.ToLLVMTy(fn.ty.Raw, context));
            for (var i = 0u; i < fn.parameters.Count; i++)
            {
                var param = fn.parameters[(int)i];
                if (param.HasName)
                    SetValueName(GetParam(self, i), param.Name + ".p");
            }
            if (fn.header.modifiers.Has(ModifierType.EXTERN))
                SetLinkage(self, LLVMLinkage.LLVMExternalLinkage);
            if (fn.body != null)
            {
                walker.StepIn();
                PositionBuilderAtEnd(builder, AppendBasicBlock(self, ".entry"));
                for (var i = 0u; i < fn.parameters.Count; i++)
                {
                    var param = fn.parameters[(int)i];

                    var sym = walker.Current.Lookup(param.Name);
                    sym.userdata = BuildAlloca(builder, TypeConverter.ToLLVMTy(param.Ty.Raw, context), param.Name);

                    BuildStore(builder, GetParam(self, i), (LLVMValueRef)sym.userdata);
                }
                var compiler = new FnCompiler(log, walker, context, module, builder, self);
                fn.body.ForEach(node => node.Accept(compiler));
                if (fn.ty.returnTy.IsVoid)
                    BuildRetVoid(builder);
                walker.StepOut();
            }
        }
Esempio n. 2
0
 public void Visit(NodeFnDecl fn)
 {
     fn.parameters.ForEach(param => ResolveTy(param.spTy));
     ResolveTy([email protected]);
     if (fn.body != null)
     {
         walker.StepIn();
         fn.body.ForEach(node => node.Accept(this));
         walker.StepOut();
     }
 }
Esempio n. 3
0
        public void Visit(NodeFnDecl fn)
        {
            if (fn.body != null)
            {
                currentFn = walker.Current.Lookup(fn.Name) as FnSymbol;

                walker.StepIn();
                fn.body.ForEach(node => node.Accept(this));
                walker.StepOut();
            }
        }
Esempio n. 4
0
 public void Visit(NodeFnDecl fn)
 {
     symbols.InsertFn(fn.Name, fn.header.modifiers, fn.ty);
     if (fn.body != null)
     {
         symbols.NewScope(fn.Name);
         fn.parameters.ForEach(param => symbols.InsertVar(param.Name, param.Ty));
         var fnAnalyzer = new FnAnalyzer(log, symbols);
         fn.body.ForEach(node => node.Accept(fnAnalyzer));
         symbols.ExitScope();
     }
 }
Esempio n. 5
0
        public void Visit(NodeFnDecl fn)
        {
            // the decl
            WriteMods(fn.header.modifiers);
            // 'fn' name '|' args ':' type ',' '|' '->' type
            Write("'fn' ");
            // TODO(kai): write this better <3
            Write(fn.Name);
            Write(" '|' ");
            var p = fn.parameters;
            for (int i = 0; i < p.Count; i++)
            {
                if (i > 0)
                    Write(" ',' ");
                WriteParameter(p[i]);
            }
            Write(" '|' ");
            // TODO(kai): change this when you have the infer type
            if (fn.@return != null)
            {
                Write("'->' ");
                if ([email protected])
                    Write("'()'");
                else WriteParameter(fn.@return);
            }
            WriteLine();

            // the body
            if (fn.body != null)
            {
                WriteTabs();
                if (fn.body.eq != null)
                    Write("'=' ");
                Write("'{'");
                Tab();
                WriteLine();
                fn.body.ForEach(node => {
                    WriteTabs();
                    node.Accept(this);
                    WriteLine();
                });
                Untab();
                WriteTabs();
                Write("'}'");
                WriteLine();
            }
        }
Esempio n. 6
0
 public void Visit(NodeFnDecl fn)
 {
     throw new NotImplementedException();
 }
Esempio n. 7
0
 public void Visit(NodeFnDecl fn)
 {
     log.Error(fn.Span, "A function is not valid in another function.");
 }
Esempio n. 8
0
        /// <summary>
        /// This can return either a NodeFN or a NodeFnDecl, depending on the precense of a body.
        /// This can still return a NodeFn for extern fns, it'll just end up being an error later (unless I do
        /// some kinda neat thing with bodied externs?)
        /// </summary>
        private NodeFnDecl ParseFn(Modifiers mods)
        {
            var fn = new NodeFnDecl();
            fn.header = new MemberHeader(mods);
            ParseFnDecl(fn);

            if (!HasCurrent)
                return fn;

            // TODO(kai): clean this up, it's ugly
            if (Check(EQ) || Check(LBRACE))
                fn.body = ParseFnBody();

            // TODO(kai): check if this is followed by an expression.
            // if it is, then we should parse that and use it as a body!

            return fn;
        }
Esempio n. 9
0
        /// <summary>
        /// This starts at the 'fn' keyword and reads until the return type.
        /// </summary>
        private void ParseFnDecl(NodeFnDecl fn)
        {
            // TODO(kai): check for no tokens?

            // The 'fn' keyword
            fn.fn = Current;
            Expect(FN, "Expected 'fn' when parsing fn declaration.");

            // Next, there'll be generic type arguments.
            // BUT WE DON'T CARE YET
            // TODO(kai): generic type arguments.

            // After that we expect a name:
            if (!HasCurrent)
            {
                log.Error(GetLastSpan(), "Expected an identifier to name the function, got end of file.");
                return;
            }

            // TODO(kai): support operators here, too.
            fn.name = NameOrOp.FromName(ExpectIdent("Expected an identifier to name the function").Image);

            // Then, the parameter list!
            fn.parameters = ParseParameterList();
            var paramTys = fn.parameters.Select(param => param.Ty).ToList();

            TyRef returnTy = InferTyRef.InferTy;

            // Next, the return type!
            if (CheckOp(ARROW))
            {
                AdvanceOp(ARROW);
                fn.@return = ParseParameter();
                returnTy = [email protected];
            }
            else returnTy = null;

            fn.ty = new FnTyRef(paramTys, returnTy);

            // That's the end of the fn decl!
        }