private static void FillDataArray(CompilerContext context, TokenizerOutput to) { ConstructorBuilder ctor = context.ProgramType.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); FieldBuilder array = context.ProgramType.DefineField("DataArray", typeof(string[]), FieldAttributes.Static | FieldAttributes.Public); context.ProgramDataList = array; ILGenerator il = ctor.GetILGenerator(); if (to.Data != null && to.Data.Count > 0) { il.Emit(OpCodes.Ldc_I4, to.Data.Count); il.Emit(OpCodes.Newarr, typeof(string)); il.Emit(OpCodes.Stsfld, array); for (int i = 0; i < to.Data.Count; ++i) { il.Emit(OpCodes.Ldsfld, array); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldstr, to.Data[i]); il.Emit(OpCodes.Stelem_Ref); } } il.Emit(OpCodes.Ret); }
public bool Load(string fileName) { Reset(); TokenizerOutput to = NBTokenizer.TokenizeFile(this, fileName); return(LoadProgram(to)); }
public bool Load(IEnumerable <string> program) { Reset(); TokenizerOutput to = NBTokenizer.Tokenize(this, program); return(LoadProgram(to)); }
private static void CheckJumps(CompilingContext context, TokenizerOutput program) { for (int i = 0; i < program.Program.Count; ++i) { Statement s = program.Program[i].Statement; if (s is KwrJump) { if (s is KwrGosub) { context.MakeReturnLabel(((KwrGosub)s).ReturnAddress); } KwrJump jmp = s as KwrJump; context.MakeLabel(jmp.JumpPos); } } }
private static void CreateProgramType(CompilerContext context, TokenizerOutput to) { TypeBuilder type = context.Module.DefineType(context.MainTypeName + "Program", TypeAttributes.Class | TypeAttributes.Public); type.DefineDefaultConstructor(MethodAttributes.Public); context.ProgramType = type; FillDataArray(context, to); MethodBuilder main = type.DefineMethod("Main", MethodAttributes.Public, typeof(bool), new[] { context.DefaultOutput.Type }); ILGenerator il = main.GetILGenerator(); context.ProgramMain = main; context.ProgramIL = il; DoCompile(context, to); context.Program = type.CreateType(); }
private bool LoadProgram(TokenizerOutput program) { _readList.Clear(); Program = null; if (program == null) { return(false); } if (program.Data != null) { _readList.AddRange(program.Data); } Program = new List <IItem>(); foreach (TLine line in program.Program) { Program.Add(Make(line)); } return(true); }
private static void DoCompile(CompilerContext outerContext, TokenizerOutput to) { var c = new CompilingContext { IL = outerContext.ProgramIL, Out = outerContext.DefaultOutput, Program = outerContext.ProgramType }; CheckJumps(c, to); // string conversion stuff c.DoubleConversionVar = c.IL.DeclareLocal(typeof(Double)); c.CharConversionVar = c.IL.DeclareLocal(typeof(char)); // data / read c.DataList = outerContext.ProgramDataList; c.DataPointer = c.Program.DefineField("DataPointer", typeof(int), FieldAttributes.Public); c.DataTempVariable = c.IL.DeclareLocal(typeof(string)); c.IL.Emit(OpCodes.Ldarg_0); c.IL.Emit(OpCodes.Ldc_I4, 0); c.IL.Emit(OpCodes.Stfld, c.DataPointer); // gosub/return stack c.GosubStack = c.IL.DeclareLocal(typeof(Stack <int>)); c.IL.Emit(OpCodes.Newobj, typeof(Stack <int>).GetConstructor(Type.EmptyTypes)); c.IL.Emit(OpCodes.Stloc, c.GosubStack); // rnd c.Rnd = c.IL.DeclareLocal(typeof(Random)); c.IL.Emit(OpCodes.Newobj, typeof(Random).GetConstructor(Type.EmptyTypes)); c.IL.Emit(OpCodes.Stloc, c.Rnd); c.EndLabel = c.IL.DefineLabel(); c.ReturnLabel = c.IL.DefineLabel(); // switch off the cursor //c.IL.Emit( OpCodes.Ldc_I4_0 ); //c.IL.Emit( OpCodes.Call, typeof( Console ).GetMethod( "set_CursorVisible" ) ); Factory f = GetFactory(); c.Factory = f; for (int i = 0; i < to.Program.Count; ++i) { TLine line = to.Program[i]; c.MarkLabelIfNeeded(i); try { f.Execute(c, line.Statement); } catch (Exception e) { Console.WriteLine("Error : " + e.Message); Console.WriteLine("Line: " + (line.OriginalLine.LineNum ?? -1).ToString()); Console.WriteLine(line.OriginalLine.OriginalLine); } } // switch the cursor on //c.IL.Emit( OpCodes.Ldc_I4_1 ); //c.IL.Emit( OpCodes.Call, typeof( Console ).GetMethod( "set_CursorVisible" ) ); MakeReturn(c); // return c.IL.MarkLabel(c.EndLabel); c.IL.Emit(OpCodes.Ldc_I4_1); c.IL.Emit(OpCodes.Ret); }
public static List <Token> Tokenize(string buffer) { TokenizerOutput ctx = new TokenizerOutput(); TokenizerState state = new TokenizerState(buffer); while (!state.IsEndOfStream()) { while (!state.IsEndOfStream() && state.GetChar() != '\n' && char.IsWhiteSpace(state.GetChar())) { state.NextChar(); } if (state.IsEndOfStream()) { break; } char c = state.GetChar(); switch (c) { case '\n': state.NextLine(); state.NextChar(); break; case '(': ctx.AddSymbol(TokenType.BraceBegin, c, state.CreateInfo()); state.NextChar(); break; case ')': ctx.AddSymbol(TokenType.BraceEnd, c, state.CreateInfo()); state.NextChar(); break; case ',': ctx.AddSymbol(TokenType.ArgumentSeparator, c, state.CreateInfo()); state.NextChar(); break; case '*': ctx.AddSymbol(TokenType.Pointer, c, state.CreateInfo()); state.NextChar(); break; default: if (char.IsLetter(c) || c == '_') { int start = state.BufferPos; while (!state.IsEndOfStream() && (char.IsLetterOrDigit(state.GetChar()) || (state.GetChar() == '_'))) { state.NextChar(); } int len = state.BufferPos - start; string ident = buffer.Substring(start, len); ctx.AddIdent(ident, state.CreateInfo()); } else { ctx.AddChar(c, state.CreateInfo()); state.NextChar(); } break; } } return(ctx.Tokens); }