static IfBlock GetIf(int blockNumber) { IfBlock ifblock = null; foreach (Block b in blocks) { if (b is IfBlock) { IfBlock bl = (IfBlock)b; if (bl.blockNumber == blockNumber) { ifblock = bl; } } } return(ifblock); }
public Lexer(string c) { c = c.Replace(((char)13).ToString(), ""); Func currentFunc = null; Block currentBlock = null; int blockNumber = 0; Stack <Block> blockstack = new Stack <Block>(); foreach (string a in c.Split('\n')) { if (a.StartsWith(":")) { string op = a.Substring(1); if (currentFunc == null) { currentFunc = new Func(op, code.buffer.Count); } else { code.Write(Opcodes.ret); funcs.Add(currentFunc); currentFunc = new Func(op, code.buffer.Count); } } else if (a.StartsWith(".")) { string name = a.Substring(1); Label l = new Label(name, code.buffer.Count()); currentFunc.labels.Add(l); } else if (a.StartsWith("pushInt ")) { int value = Convert.ToInt32(a.Substring(10)); code.Write(Opcodes.pushInt); code.Write(value); } else if (a.StartsWith("pushString ")) { string temp = a.Substring(11); string value = temp.Substring(temp.IndexOf("\"") + 1, temp.LastIndexOf("\"") - 1); code.Write(Opcodes.pushString); code.Write(value); } else if (a.StartsWith("pushVar ")) { string name = a.Substring(8); code.Write(Opcodes.pushVar); code.Write(name); } else if (a == "print") { code.Write(Opcodes.print); } else if (a == "printLine") { code.Write(Opcodes.printLine); } else if (a == "read") { code.Write(Opcodes.read); } else if (a == "readLine") { code.Write(Opcodes.readLine); } else if (a == "halt") { code.Write(Opcodes.halt); } else if (a == "inputInt32") { code.Write(Opcodes.inputInt32); } else if (a == "inputString") { code.Write(Opcodes.inputString); } else if (a == "pop") { code.Write(Opcodes.pop); } else if (a == "popa") { code.Write(Opcodes.popa); } else if (a.StartsWith("decVar ")) { string name = a.Substring(7); code.Write(Opcodes.decVar); code.Write(name); } else if (a.StartsWith("setVar ")) { string name = a.Substring(7); code.Write(Opcodes.setVar); code.Write(name); } else if (a == "add") { code.Write(Opcodes.add); } else if (a == "sub") { code.Write(Opcodes.sub); } else if (a == "mul") { code.Write(Opcodes.mul); } else if (a == "div") { code.Write(Opcodes.div); } else if (a == "clear") { code.Write(Opcodes.clear); } else if (a == "ife") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new IfBlock(blockNumber); code.Write(Opcodes.ife); code.Write(blockNumber); blockNumber++; } else if (a == "ifn") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new IfBlock(blockNumber); code.Write(Opcodes.ifn); code.Write(blockNumber); blockNumber++; } else if (a == "elseife") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new ElseIfBlock(blockNumber); code.Write(Opcodes.elseife); code.Write(blockNumber); blockNumber++; } else if (a == "elseifn") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new ElseIfBlock(blockNumber); code.Write(Opcodes.elseifn); code.Write(blockNumber); blockNumber++; } else if (a == "else") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new ElseBlock(blockNumber); code.Write(Opcodes.els); code.Write(blockNumber); blockNumber++; } else if (a == "endif") { code.Write(Opcodes.endif); currentBlock.endBlock = code.buffer.Count(); blocks.Add(currentBlock); if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); } else { currentBlock = null; } } else if (a.StartsWith("call ")) { string name = a.Substring(5); code.Write(Opcodes.call); code.Write(name); } else if (a.StartsWith("goto ")) { string name = a.Substring(5); code.Write(Opcodes.got); code.Write(name); } else if (a == "ret") { code.Write(Opcodes.ret); } } code.Write(Opcodes.ret); funcs.Add(currentFunc); }
static void Run(Func func) { int opcode = 0; code.pos = func.location; currentFunc = func; Block currentBlock = null; Stack <Block> blockstack = new Stack <Block>(); while (running) { try { opcode = code.ReadInt(); } catch { } if (opcode == Opcodes.pushInt) { stack.Push(code.ReadInt()); } else if (opcode == Opcodes.pushString) { stack.Push(code.ReadString()); } else if (opcode == Opcodes.pushVar) { stack.Push(GetVarValue(code.ReadString())); } else if (opcode == Opcodes.print) { Console.Write(stack.Pop()); } else if (opcode == Opcodes.printLine) { Console.WriteLine(stack.Pop()); } else if (opcode == Opcodes.read) { Console.Read(); } else if (opcode == Opcodes.readLine) { Console.ReadLine(); } else if (opcode == Opcodes.halt) { while (true) { } } else if (opcode == Opcodes.inputInt32) { stack.Push(Convert.ToInt32(Console.ReadLine())); } else if (opcode == Opcodes.inputString) { stack.Push(Console.ReadLine()); } else if (opcode == Opcodes.pop) { stack.Pop(); } else if (opcode == Opcodes.popa) { stack.Clear(); } else if (opcode == Opcodes.decVar) { vars.Add(new Var(code.ReadString())); } else if (opcode == Opcodes.setVar) { SetVarValue(code.ReadString(), stack.Pop()); } else if (opcode == Opcodes.add) { object value1 = stack.Pop(); object value2 = stack.Pop(); if (value1 is string && value2 is string) { string value = ((string)value2) + ((string)value1); stack.Push(value); } else if (value1 is int && value2 is int) { int value = ((int)value1) + ((int)value2); stack.Push(value); } } else if (opcode == Opcodes.sub) { int value1 = (int)stack.Pop(); int value2 = (int)stack.Pop(); stack.Push(value1 + value2); } else if (opcode == Opcodes.mul) { int value1 = (int)stack.Pop(); int value2 = (int)stack.Pop(); stack.Push(value1 * value2); } else if (opcode == Opcodes.div) { int value1 = (int)stack.Pop(); int value2 = (int)stack.Pop(); stack.Push(value1 / value2); } else if (opcode == Opcodes.clear) { Console.Clear(); } else if (opcode == Opcodes.ife) { int blockNumber = code.ReadInt(); IfBlock ifblock = GetIf(blockNumber); object value1 = stack.Pop(); object value2 = stack.Pop(); if (IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = ifblock; } else { blockstack.Push(currentBlock); currentBlock = ifblock; } IncVars(); ifWorked = true; } else { code.pos = ifblock.endBlock; ifWorked = false; } } else if (opcode == Opcodes.ifn) { int blockNumber = code.ReadInt(); IfBlock ifblock = GetIf(blockNumber); object value1 = stack.Pop(); object value2 = stack.Pop(); if (!IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = ifblock; } else { blockstack.Push(currentBlock); currentBlock = ifblock; } IncVars(); ifWorked = true; } else { code.pos = ifblock.endBlock; ifWorked = false; } } else if (opcode == Opcodes.elseife) { int blockNumber = code.ReadInt(); ElseIfBlock elseifblock = GetElseIf(blockNumber); if (!ifWorked) { object value1 = stack.Pop(); object value2 = stack.Pop(); if (IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = elseifblock; } else { blockstack.Push(currentBlock); currentBlock = elseifblock; } IncVars(); ifWorked = true; } else { code.pos = elseifblock.endBlock; ifWorked = false; } } else { code.pos = elseifblock.endBlock; } } else if (opcode == Opcodes.elseifn) { int blockNumber = code.ReadInt(); ElseIfBlock elseifblock = GetElseIf(blockNumber); if (!ifWorked) { object value1 = stack.Pop(); object value2 = stack.Pop(); if (!IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = elseifblock; } else { blockstack.Push(currentBlock); currentBlock = elseifblock; } IncVars(); ifWorked = true; } else { code.pos = elseifblock.endBlock; ifWorked = false; } } else { code.pos = elseifblock.endBlock; } } else if (opcode == Opcodes.els) { int blockNumber = code.ReadInt(); ElseBlock elseblock = GetElse(blockNumber); if (!ifWorked) { if (currentBlock == null) { currentBlock = elseblock; } else { blockstack.Push(currentBlock); currentBlock = elseblock; } IncVars(); } else { code.pos = elseblock.endBlock; } } else if (opcode == Opcodes.endif) { if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); } else { currentBlock = null; } DecVars(); } else if (opcode == Opcodes.call) { string name = code.ReadString(); Func f = GetFunc(name); Call c = new Call(currentFunc, code.pos, vars); callstack.Push(c); currentFunc = f; code.pos = f.location; vars.Clear(); } else if (opcode == Opcodes.got) { string name = code.ReadString(); int location = GetLabel(name); code.pos = location; } else if (opcode == Opcodes.ret) { if (callstack.Count > 0) { Call c = callstack.Pop(); currentFunc = c.func; code.pos = c.ret; vars = c.vars; } else { running = false; } } } }