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(); } }
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(); } }
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(); } }
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(); } }
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(); } }
public void Visit(NodeFnDecl fn) { throw new NotImplementedException(); }
public void Visit(NodeFnDecl fn) { log.Error(fn.Span, "A function is not valid in another function."); }
/// <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; }
/// <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! }