/// <summary> /// Builds subroutine /// </summary> /// <param name="subNode">Subroutine node</param> /// <param name="subSym">Subroutine symbol</param> private void BuildSubroutine(ASTSubStatementNode subNode, UserSubroutine subSym) { _context = new MethodContext(_codeHolder.GetMethodBuilder(subNode.Name, subSym), subSym.GetLocalsList()); _emitter = new CodeEmiter(_context.ILGenerator); if (subNode.Body != null) { BuildStatement(subNode.Body); } else { _emitter.Nop(); } _emitter.MarkLabel(_context.MethodEnd); _emitter.Ret(); _builtSubs.Add(subNode.Name, _context); //add to built }
public MethodBuilder GetMethodBuilder(string name, UserSubroutine symbol) { MethodBuilder mb; mb = _typeBuilder.DefineMethod( name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig ); if (symbol.Return) { mb.SetReturnType(typeof(object)); } if (symbol.ArgumentsCount > 0) { mb.SetParameters(Enumerable.Repeat(typeof(object), symbol.ArgumentsCount).ToArray()); } return(mb); }
private void VisitSubStatement(ASTSubStatementNode subNode) { //check overriding var existsSub = (ISubroutine)Symbols.FindSymbol(subNode.Name); if (existsSub != null) { if (existsSub is NativeSubroutine) { Messages.Add(new MessageRecord(MsgCode.NativeSubOverride, subNode.SourcePath, subNode.StartLine, subNode.StartPos, subNode.Name)); } else { Messages.Add(new MessageRecord(MsgCode.UserSubOverride, subNode.SourcePath, subNode.StartLine, subNode.StartPos, subNode.Name)); } } else { UserSubroutine sub = new UserSubroutine(subNode); //add arguments if (subNode.ArgList != null) { foreach (var a in subNode.ArgList.Arguments) { sub.AddLocal(a.Name, new Argument()); } } _currentSubroutine = sub; //body check if (subNode.Body != null) { VisitBodyStatement(subNode.Body); } Symbols.AddSymbol(subNode.Name, _currentSubroutine); } }