using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace ASM { public partial class Form1 : Form { enum Opcode { nop = 0, end = 1, mov1 = 2, mov2 = 3, mov4 = 4, mov8 = 5, z2r = 6, r2z = 7, z2char = 8, char2z = 9, add4 = 10, add8 = 11, sub4 = 12, sub8 = 13, mul4 = 14, mul8 = 15, div4 = 16, div8 = 17, mod = 18, and1 = 19, and4 = 20, or1 = 21, or4 = 22, xor1 = 23, xor4 = 24, not1 = 25, not4 = 26, shl = 27, shr = 28, eq1 = 29, eq2 = 30, eq4 = 31, eq8 = 32, lt4 = 33, lt8 = 34, gt4 = 35, gt8 = 36, jmp = 37, jmpc = 38, push1 = 39, push2 = 40, push4 = 41, push8 = 42, pop1 = 43, pop2 = 44, pop4 = 45, pop8 = 46, call = 47, ret = 48, pow = 52, log = 53, sin = 54, cos = 55, tan = 56, asin = 57, acos = 58, atan = 59, rnd = 60, rndi = 61, tick = 62, ticksh = 63, new_ = 64, del = 65, size = 66, doe = 67, debug = 68, exdel = 69, z2str = 70, z2strb = 71, z2strh = 72, r2str = 73, str2z = 74, strb2z = 75, strh2z = 76, str2r = 77, arrcpy = 78, arrcmp = 79, newreader = 80, newwriter = 81, closereader = 82, closewriter = 83, readerlen = 84, read1 = 85, read2 = 86, read4 = 87, read8 = 88, readarray = 89, write1 = 90, write2 = 91, write4 = 92, write8 = 93, writearray = 94, key = 95, left = 96, right = 97, middle = 98, mousedz = 99, mousex = 100, mousey = 101, clear = 102, present = 103, newsurf = 104, surfdx = 105, surfdy = 106, blt = 107, drawline = 108, drawbox = 109, drawrbox = 110, drawellipse = 111, drawtext = 112, newsndbuf = 113, getvolume = 114, setvolume = 115, play = 116, stop = 117, } enum Addressing { Immediate = 0, X = 1, HP = 2, Data = 3, Stack = 4, Heap = 5, } enum TokenType { None = 0, Identifier, Opcode, LabelMark, LabelValue, Comma, Bool, Char, Z, R, X, HP, Data, Stack, Heap, } struct Token { public TokenType Type; public string Value; public Token(TokenType type, string value) { Type = type; Value = value; } } struct Mov { public string LabelMark; // nullにしてもよい public Opcode TheOpcode; public Addressing DestAddressing; public string Dest; public bool SrcIsLabelValue; public Addressing SrcAddressing; public string Src; } struct Other { public string LabelMark; // nullにしてもよい public Opcode TheOpcode; public byte[] Xs; public Other(string labelMark, Opcode theOpcode, byte[] xs) { LabelMark = labelMark; TheOpcode = theOpcode; Xs = xs; } } public Form1() { InitializeComponent(); } private void UIOK_Click(object sender, EventArgs e) { if (UIAsm.Text.Length == 0) return; List<string> asmLines = new List<string>(); // 空の行も含まれる List<List<Token>> tokenLines = new List<List<Token>>(); // 空の行も含まれる List<object> codeLines = new List<object>(); // 空の行も含まれる、MovかOtherを格納する int lastIndex = 0; for (int i = 0; i < UIAsm.Text.Length; i++) { if (UIAsm.Text[i] == '\r' && UIAsm.Text[i + 1] == '\n') { asmLines.Add(UIAsm.Text.Substring(lastIndex, i - lastIndex)); i++; lastIndex = i + 1; } else if (i == UIAsm.Text.Length - 1) { asmLines.Add(UIAsm.Text.Substring(lastIndex, i - lastIndex + 1)); break; } } for (int i = 0; i < asmLines.Count; i++) { tokenLines.Add(new List<Token>()); for (int j = 0; j < asmLines[i].Length; ) { Token? token; try { token = NextToken(asmLines[i], ref j); } catch (Exception) { UIError.Text = "error! (line: " + i.ToString() +")"; return; } if (token == null) break; Token token_ = token.Value; if (token_.Type == TokenType.Identifier) token_ = CheckIdentifier(token_); if (token_.Type == TokenType.LabelMark) if (!CheckLabelMark(token_)) { UIError.Text = "error! (line: " + i.ToString() + ")"; return; } tokenLines[i].Add(token_); } } for (int i = 0; i < tokenLines.Count; i++) { if (tokenLines[i].Count == 0) { codeLines.Add(null); continue; } try { string tLabelMark; if (tokenLines[i][0].Type == TokenType.LabelMark) { if (tokenLines[i].Count < 2) throw new Exception(); tLabelMark = tokenLines[i][0].Value; } else { tLabelMark = null; } if (tokenLines[i][tLabelMark == null ? 0 : 1].Type != TokenType.Opcode) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov1" || tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov2" || tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov4" || tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov8") { if (tokenLines[i].Count != (tLabelMark == null ? 4 : 5)) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 2 : 3].Type != TokenType.Comma) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.Bool || tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.Char || tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.Z || tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.R || tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.LabelValue) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.Bool || tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.Char || tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.Z || tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.R) { if (tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov1") { if (tokenLines[i][tLabelMark == null ? 3 : 4].Type != TokenType.Bool) throw new Exception(); } else if (tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov2") { if (tokenLines[i][tLabelMark == null ? 3 : 4].Type != TokenType.Char) throw new Exception(); } else if (tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov4") { if (tokenLines[i][tLabelMark == null ? 3 : 4].Type != TokenType.Z) throw new Exception(); } else if (tokenLines[i][tLabelMark == null ? 0 : 1].Value == "mov8") { if (tokenLines[i][tLabelMark == null ? 3 : 4].Type != TokenType.R) throw new Exception(); } } if (tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.HP || tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.HP || tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.LabelValue) if (tokenLines[i][tLabelMark == null ? 0 : 1].Value != "mov4") throw new Exception(); if (tokenLines[i][tLabelMark == null ? 1 : 2].Type == TokenType.HP) if (tokenLines[i][tLabelMark == null ? 3 : 4].Type == TokenType.Z) throw new Exception(); // mov4 hp, 123 に対応しない Mov tMov = new Mov(); tMov.LabelMark = tLabelMark; switch (tokenLines[i][tLabelMark == null ? 0 : 1].Value) { case "mov1": tMov.TheOpcode = Opcode.mov1; break; case "mov2": tMov.TheOpcode = Opcode.mov2; break; case "mov4": tMov.TheOpcode = Opcode.mov4; break; case "mov8": tMov.TheOpcode = Opcode.mov8; break; } switch (tokenLines[i][tLabelMark == null ? 1 : 2].Type) { case TokenType.X: tMov.DestAddressing = Addressing.X; break; case TokenType.HP: tMov.DestAddressing = Addressing.HP; break; case TokenType.Data: tMov.DestAddressing = Addressing.Data; break; case TokenType.Stack: tMov.DestAddressing = Addressing.Stack; break; case TokenType.Heap: tMov.DestAddressing = Addressing.Heap; break; } tMov.Dest = tokenLines[i][tLabelMark == null ? 1 : 2].Value; switch (tokenLines[i][tLabelMark == null ? 3 : 4].Type) { case TokenType.LabelValue: tMov.SrcIsLabelValue = true; tMov.SrcAddressing = Addressing.Immediate; break; case TokenType.Bool: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Immediate; break; case TokenType.Char: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Immediate; break; case TokenType.Z: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Immediate; Int32.Parse(tokenLines[i][tLabelMark == null ? 3 : 4].Value); // テストのみ、戻り値を無視する ("-"のみの場合、lexerではなく、ここで例外を!) break; case TokenType.R: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Immediate; double.Parse(tokenLines[i][tLabelMark == null ? 3 : 4].Value); // テストのみ、戻り値を無視する break; case TokenType.X: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.X; break; case TokenType.HP: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.HP; break; case TokenType.Data: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Data; break; case TokenType.Stack: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Stack; break; case TokenType.Heap: tMov.SrcIsLabelValue = false; tMov.SrcAddressing = Addressing.Heap; break; } tMov.Src = tokenLines[i][tLabelMark == null ? 3 : 4].Value; codeLines.Add(tMov); } else { List<byte> tXs = new List<byte>(); if (tokenLines[i].Count >= (tLabelMark == null ? 2 : 3)) { if (tokenLines[i][tLabelMark == null ? 1 : 2].Type != TokenType.X) throw new Exception(); byte tX = byte.Parse(tokenLines[i][tLabelMark == null ? 1 : 2].Value.Substring(1)); if (tX > 15) throw new Exception(); tXs.Add(tX); if (tokenLines[i].Count >= (tLabelMark == null ? 3 : 4)) { if (tokenLines[i][tLabelMark == null ? 2 : 3].Type != TokenType.Comma) throw new Exception(); if (tokenLines[i].Count < (tLabelMark == null ? 4 : 5)) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 3 : 4].Type != TokenType.X) throw new Exception(); tX = byte.Parse(tokenLines[i][tLabelMark == null ? 3 : 4].Value.Substring(1)); if (tX > 15) throw new Exception(); tXs.Add(tX); if (tokenLines[i].Count >= (tLabelMark == null ? 5 : 6)) { if (tokenLines[i][tLabelMark == null ? 4 : 5].Type != TokenType.Comma) throw new Exception(); if (tokenLines[i].Count < (tLabelMark == null ? 6 : 7)) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 5 : 6].Type != TokenType.X) throw new Exception(); tX = byte.Parse(tokenLines[i][tLabelMark == null ? 5 : 6].Value.Substring(1)); if (tX > 15) throw new Exception(); tXs.Add(tX); if (tokenLines[i].Count >= (tLabelMark == null ? 7 : 8)) { if (tokenLines[i].Count != (tLabelMark == null ? 12 : 13)) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 6 : 7].Type != TokenType.Comma || tokenLines[i][tLabelMark == null ? 8 : 9].Type != TokenType.Comma || tokenLines[i][tLabelMark == null ? 10 : 11].Type != TokenType.Comma) throw new Exception(); if (tokenLines[i][tLabelMark == null ? 7 : 8].Type != TokenType.X || tokenLines[i][tLabelMark == null ? 9 : 10].Type != TokenType.X || tokenLines[i][tLabelMark == null ? 11 : 12].Type != TokenType.X) throw new Exception(); tX = byte.Parse(tokenLines[i][tLabelMark == null ? 7 : 8].Value.Substring(1)); if (tX > 15) throw new Exception(); tXs.Add(tX); tX = byte.Parse(tokenLines[i][tLabelMark == null ? 9 : 10].Value.Substring(1)); if (tX > 15) throw new Exception(); tXs.Add(tX); tX = byte.Parse(tokenLines[i][tLabelMark == null ? 11 : 12].Value.Substring(1)); if (tX > 15) throw new Exception(); tXs.Add(tX); } } } } if (tXs.Count > 1) for (int j = 0; j < tXs.Count; j++) for (int k = 0; k < tXs.Count; k++) { if (k == j) continue; if (tXs[k] == tXs[j]) throw new Exception(); } switch (tokenLines[i][tLabelMark == null ? 0 : 1].Value) { case "nop": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.nop, tXs.ToArray())); break; case "end": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.end, tXs.ToArray())); break; case "z2r": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.z2r, tXs.ToArray())); break; case "r2z": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.r2z, tXs.ToArray())); break; case "z2char": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.z2char, tXs.ToArray())); break; case "char2z": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.char2z, tXs.ToArray())); break; case "add4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.add4, tXs.ToArray())); break; case "add8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.add8, tXs.ToArray())); break; case "sub4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.sub4, tXs.ToArray())); break; case "sub8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.sub8, tXs.ToArray())); break; case "mul4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.mul4, tXs.ToArray())); break; case "mul8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.mul8, tXs.ToArray())); break; case "div4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.div4, tXs.ToArray())); break; case "div8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.div8, tXs.ToArray())); break; case "mod": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.mod, tXs.ToArray())); break; case "and1": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.and1, tXs.ToArray())); break; case "and4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.and4, tXs.ToArray())); break; case "or1": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.or1, tXs.ToArray())); break; case "or4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.or4, tXs.ToArray())); break; case "xor1": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.xor1, tXs.ToArray())); break; case "xor4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.xor4, tXs.ToArray())); break; case "not1": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.not1, tXs.ToArray())); break; case "not4": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.not4, tXs.ToArray())); break; case "shl": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.shl, tXs.ToArray())); break; case "shr": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.shr, tXs.ToArray())); break; case "eq1": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.eq1, tXs.ToArray())); break; case "eq2": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.eq2, tXs.ToArray())); break; case "eq4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.eq4, tXs.ToArray())); break; case "eq8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.eq8, tXs.ToArray())); break; case "lt4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.lt4, tXs.ToArray())); break; case "lt8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.lt8, tXs.ToArray())); break; case "gt4": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.gt4, tXs.ToArray())); break; case "gt8": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.gt8, tXs.ToArray())); break; case "jmp": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.jmp, tXs.ToArray())); break; case "jmpc": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.jmpc, tXs.ToArray())); break; case "push1": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.push1, tXs.ToArray())); break; case "push2": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.push2, tXs.ToArray())); break; case "push4": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.push4, tXs.ToArray())); break; case "push8": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.push8, tXs.ToArray())); break; case "pop1": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.pop1, tXs.ToArray())); break; case "pop2": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.pop2, tXs.ToArray())); break; case "pop4": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.pop4, tXs.ToArray())); break; case "pop8": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.pop8, tXs.ToArray())); break; case "call": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.call, tXs.ToArray())); break; case "ret": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.ret, tXs.ToArray())); break; case "pow": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.pow, tXs.ToArray())); break; case "log": if (tXs.Count != 3) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.log, tXs.ToArray())); break; case "sin": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.sin, tXs.ToArray())); break; case "cos": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.cos, tXs.ToArray())); break; case "tan": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.tan, tXs.ToArray())); break; case "asin": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.asin, tXs.ToArray())); break; case "acos": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.acos, tXs.ToArray())); break; case "atan": if (tXs.Count != 2) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.atan, tXs.ToArray())); break; case "rnd": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.rnd, tXs.ToArray())); break; case "rndi": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.rndi, tXs.ToArray())); break; case "tick": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.tick, tXs.ToArray())); break; case "ticksh": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.ticksh, tXs.ToArray())); break; case "new": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.new_, tXs.ToArray())); break; case "del": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.del, tXs.ToArray())); break; case "size": if (tXs.Count != 1) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.size, tXs.ToArray())); break; case "doe": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.doe, tXs.ToArray())); break; case "deb?uug": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.debug, tXs.ToArray())); break; case "exdel": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.exdel, tXs.ToArray())); break; case "z2str": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.z2str, tXs.ToArray())); break; case "z2strb": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.z2strb, tXs.ToArray())); break; case "z2strh": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.z2strh, tXs.ToArray())); break; case "r2str": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.r2str, tXs.ToArray())); break; case "str2z": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.str2z, tXs.ToArray())); break; case "strb2z": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.strb2z, tXs.ToArray())); break; case "strh2z": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.strh2z, tXs.ToArray())); break; case "str2r": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.str2r, tXs.ToArray())); break; case "arrcpy": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.arrcpy, tXs.ToArray())); break; case "arrcmp": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.arrcmp, tXs.ToArray())); break; case "newreader": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.newreader, tXs.ToArray())); break; case "newwriter": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.newwriter, tXs.ToArray())); break; case "closereader": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.closereader, tXs.ToArray())); break; case "closewriter": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.closewriter, tXs.ToArray())); break; case "readerlen": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.readerlen, tXs.ToArray())); break; case "read1": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.read1, tXs.ToArray())); break; case "read2": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.read2, tXs.ToArray())); break; case "read4": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.read4, tXs.ToArray())); break; case "read8": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.read8, tXs.ToArray())); break; case "readarray": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.readarray, tXs.ToArray())); break; case "write1": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.write1, tXs.ToArray())); break; case "write2": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.write2, tXs.ToArray())); break; case "write4": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.write4, tXs.ToArray())); break; case "write8": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.write8, tXs.ToArray())); break; case "writearray": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.writearray, tXs.ToArray())); break; case "key": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.key, tXs.ToArray())); break; case "left": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.left, tXs.ToArray())); break; case "right": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.right, tXs.ToArray())); break; case "middle": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.middle, tXs.ToArray())); break; case "mousedz": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.mousedz, tXs.ToArray())); break; case "mousex": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.mousex, tXs.ToArray())); break; case "mousey": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.mousey, tXs.ToArray())); break; case "clear": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.clear, tXs.ToArray())); break; case "present": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.present, tXs.ToArray())); break; case "newsurf": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.newsurf, tXs.ToArray())); break; case "surfdx": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.surfdx, tXs.ToArray())); break; case "surfdy": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.surfdy, tXs.ToArray())); break; case "blt": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.blt, tXs.ToArray())); break; case "drawline": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.drawline, tXs.ToArray())); break; case "drawbox": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.drawbox, tXs.ToArray())); break; case "drawrbox": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.drawrbox, tXs.ToArray())); break; case "drawellipse": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.drawellipse, tXs.ToArray())); break; case "drawtext": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.drawtext, tXs.ToArray())); break; case "newsndbuf": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.newsndbuf, tXs.ToArray())); break; case "getvolume": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.getvolume, tXs.ToArray())); break; case "setvolume": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.setvolume, tXs.ToArray())); break; case "play": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.play, tXs.ToArray())); break; case "stop": if (tXs.Count != 0) throw new Exception(); codeLines.Add(new Other(tLabelMark, Opcode.stop, tXs.ToArray())); break; } } } catch (Exception) { UIError.Text = "error! (line: " + i.ToString() + ")"; return; } } bool tEmptyCode = true; foreach (object i in codeLines) if (i != null) tEmptyCode = false; if (tEmptyCode) return; uint[] addrOfEachLine = new uint[codeLines.Count]; for (int i = 0; i < codeLines.Count - 1; i++) addrOfEachLine[i + 1] = addrOfEachLine[i] + CalcCodeSize(codeLines[i]); Dictionary<string, uint> LabelMap = new Dictionary<string,uint>(); for (int i = 0; i < codeLines.Count; i++) { string tLabelMark = null; if (codeLines[i] is Mov) tLabelMark = ((Mov)codeLines[i]).LabelMark; else if (codeLines[i] is Other) tLabelMark = ((Other)codeLines[i]).LabelMark; if (tLabelMark != null) { if (LabelMap.ContainsKey(tLabelMark)) { throw new Exception(); } else { LabelMap.Add(tLabelMark, addrOfEachLine[i]); } } } for (int i = 0; i < codeLines.Count; i++) { if (codeLines[i] is Mov) { Mov tMov = (Mov)codeLines[i]; if (tMov.SrcIsLabelValue) { if (!LabelMap.ContainsKey(tMov.Src)) throw new Exception(); tMov.Src = LabelMap[tMov.Src].ToString(); tMov.SrcIsLabelValue = false; codeLines[i] = tMov; } } } if (UISaveFile.ShowDialog() != System.Windows.Forms.DialogResult.OK) return; BinaryWriter w = new BinaryWriter(UISaveFile.OpenFile()); for (int i = 0; i < codeLines.Count; i++) { if (codeLines[i] == null) continue; if (codeLines[i] is Mov) { Mov tMov = (Mov)codeLines[i]; w.Write((byte)tMov.TheOpcode); w.Write((byte)tMov.DestAddressing); switch (tMov.DestAddressing) { case Addressing.X: w.Write(byte.Parse(tMov.Dest.Substring(1))); break; case Addressing.HP: break; case Addressing.Data: w.Write(Int32.Parse(tMov.Dest)); break; case Addressing.Stack: w.Write(Int32.Parse(tMov.Dest)); break; case Addressing.Heap: w.Write(byte.Parse(tMov.Dest)); break; } w.Write((byte)tMov.SrcAddressing); switch (tMov.SrcAddressing) { case Addressing.Immediate: switch (tMov.TheOpcode) { case Opcode.mov1: if (tMov.Src == "true") w.Write((byte)0xFF); else if (tMov.Src == "false") w.Write((byte)0x00); break; case Opcode.mov2: w.Write((Int16)tMov.Src[0]); break; case Opcode.mov4: w.Write(Int32.Parse(tMov.Src)); break; case Opcode.mov8: w.Write(Double.Parse(tMov.Src)); break; } break; case Addressing.X: w.Write(byte.Parse(tMov.Src.Substring(1))); break; case Addressing.HP: break; case Addressing.Data: w.Write(Int32.Parse(tMov.Src)); break; case Addressing.Stack: w.Write(Int32.Parse(tMov.Src)); break; case Addressing.Heap: w.Write(byte.Parse(tMov.Src)); break; } } else if (codeLines[i] is Other) { Other tOther = (Other)codeLines[i]; w.Write((byte)tOther.TheOpcode); for (int j = 0; j < tOther.Xs.Length; j++) w.Write((byte)tOther.Xs[j]); } } w.Close(); UIError.Text = "OK!"; } Token? NextToken(string l, ref int i) // 空の行はnullを戻す { if (l.Length == 0) return null; Token t = new Token(TokenType.None, ""); _Start: if (i >= l.Length) { return null; } else if (l[i] == ' ' || l[i] == '\t') { i++; goto _Start; } else if (l[i] == 'x') { t.Value += l[i]; i++; goto _X; } // "x"から始まるidentifierにも対応する! else if (l[i] == 'h') { t.Value += l[i]; i++; goto _HP; } // "h"から始まるidentifierにも対応する! else if (l[i] >= 'a' && l[i] <= 'z') { t.Value += l[i]; i++; goto _Identifier; } else if ((l[i] >= '0' && l[i] <= '9') || l[i] == '-') { t.Value += l[i]; i++; goto _Z; } else if (l[i] == '\'') { i++; goto _Char; } else if (l[i] == ',') { i++; t.Value = null; t.Type = TokenType.Comma; return t; } else if (l[i] == '[') { i++; goto _Left; } else { throw new Exception(); } _Identifier: if (i >= l.Length) { t.Type = TokenType.Identifier; return t; } else if (l[i] == ' ' || l[i] == '\t') { i++; t.Type = TokenType.Identifier; return t; } else if (l[i] >= 'a' && l[i] <= 'z') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] == '\'') { t.Type = TokenType.Identifier; return t; } else if (l[i] == ',') { t.Type = TokenType.Identifier; return t; } else if (l[i] == '[') { t.Type = TokenType.Identifier; return t; } else if (l[i] == ':') { i++; t.Type = TokenType.LabelMark; return t; } else { throw new Exception(); } _Z: if (i >= l.Length) { t.Type = TokenType.Z; return t; } // "-"のみの場合、このlexerでは処理しなく、あとのInt32.Parseのテストで例外を! else if (l[i] == ' ' || l[i] == '\t') { t.Type = TokenType.Z; return t; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Z; } else if (l[i] == '.') { t.Value += l[i]; i++; goto _R; } else if (l[i] == '\'') { t.Type = TokenType.Z; return t; } else if (l[i] == ',') { t.Type = TokenType.Z; return t; } else if (l[i] == '[') { t.Type = TokenType.Z; return t; } else { throw new Exception(); } _R: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _R2; } else { throw new Exception(); } _R2: if (i >= l.Length) { t.Type = TokenType.R; return t; } else if (l[i] == ' ' || l[i] == '\t') { t.Type = TokenType.R; return t; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _R2; } else if (l[i] == '\'') { t.Type = TokenType.R; return t; } else if (l[i] == ',') { t.Type = TokenType.R; return t; } else if (l[i] == '[') { t.Type = TokenType.R; return t; } else { throw new Exception(); } _Char: if (i >= l.Length) { throw new Exception(); } else if (l[i] == '\'') { throw new Exception(); } else { t.Value += l[i]; i++; goto _Char2; } _Char2: if (i >= l.Length) { throw new Exception(); } else if (l[i] == '\'') { i++; t.Type = TokenType.Char; return t; } else { throw new Exception(); } _X: if (i >= l.Length) { t.Type = TokenType.Identifier; return t; } else if (l[i] == ' ' || l[i] == '\t') { t.Type = TokenType.Identifier; return t; } else if (l[i] >= 'a' && l[i] <= 'z') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _X2; } else if (l[i] == '\'') { t.Type = TokenType.Identifier; return t; } else if (l[i] == ',') { t.Type = TokenType.Identifier; return t; } else if (l[i] == '[') { t.Type = TokenType.Identifier; return t; } else if (l[i] == ':') { i++; t.Type = TokenType.LabelMark; return t; } else { throw new Exception(); } _X2: if (i >= l.Length) { t.Type = TokenType.X; return t; } else if (l[i] == ' ' || l[i] == '\t') { t.Type = TokenType.X; return t; } else if (l[i] >= 'a' && l[i] <= 'z') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _X2; } else if (l[i] == '\'') { t.Type = TokenType.X; return t; } else if (l[i] == ',') { t.Type = TokenType.X; return t; } else if (l[i] == '[') { t.Type = TokenType.X; return t; } else { throw new Exception(); } _HP: if (i >= l.Length) { t.Type = TokenType.Identifier; return t; } else if (l[i] == ' ' || l[i] == '\t') { t.Type = TokenType.Identifier; return t; } else if (l[i] == 'p') { t.Value += l[i]; i++; goto _HP2; } else if (l[i] >= 'a' && l[i] <= 'z') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] == '\'') { t.Type = TokenType.Identifier; return t; } else if (l[i] == ',') { t.Type = TokenType.Identifier; return t; } else if (l[i] == '[') { t.Type = TokenType.Identifier; return t; } else if (l[i] == ':') { i++; t.Type = TokenType.LabelMark; return t; } else { throw new Exception(); } _HP2: if (i >= l.Length) { t.Value = null; t.Type = TokenType.HP; return t; } else if (l[i] == ' ' || l[i] == '\t') { t.Value = null; t.Type = TokenType.HP; return t; } else if (l[i] >= 'a' && l[i] <= 'z') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Identifier; } else if (l[i] == '\'') { t.Value = null; t.Type = TokenType.HP; return t; } else if (l[i] == ',') { t.Value = null; t.Type = TokenType.HP; return t; } else if (l[i] == '[') { t.Value = null; t.Type = TokenType.HP; return t; } else { throw new Exception(); } _Left: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Data; } else if (l[i] == 's') { i++; goto _Stack; } else if (l[i] == 'h') { i++; goto _Heap; } else { throw new Exception(); } _Data: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Data; } else if (l[i] == ']') { i++; t.Type = TokenType.Data; return t; } else { throw new Exception(); } _Stack: if (i >= l.Length) { throw new Exception(); } else if (l[i] == 'p') { i++; goto _Stack2; } else { throw new Exception(); } _Stack2: if (i >= l.Length) { throw new Exception(); } else if (l[i] == '-') { i++; goto _Stack3; } else { throw new Exception(); } _Stack3: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Stack4; } else { throw new Exception(); } _Stack4: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Stack4; } else if (l[i] == ']') { i++; t.Type = TokenType.Stack; return t; } else { throw new Exception(); } _Heap: if (i >= l.Length) { throw new Exception(); } else if (l[i] == 'p') { i++; goto _Heap2; } else { throw new Exception(); } _Heap2: if (i >= l.Length) { throw new Exception(); } else if (l[i] == '-') { i++; goto _Heap3; } else { throw new Exception(); } _Heap3: if (i >= l.Length) { throw new Exception(); } else if (l[i] == '>') { i++; goto _Heap4; } else { throw new Exception(); } _Heap4: if (i >= l.Length) { throw new Exception(); } else if (l[i] == 'x') { i++; goto _Heap5; } else { throw new Exception(); } _Heap5: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Heap6; } else { throw new Exception(); } _Heap6: if (i >= l.Length) { throw new Exception(); } else if (l[i] >= '0' && l[i] <= '9') { t.Value += l[i]; i++; goto _Heap6; } else if (l[i] == ']') { i++; t.Type = TokenType.Heap; return t; } else { throw new Exception(); } } Token CheckIdentifier(Token x) { if (x.Type != TokenType.Identifier) throw new Exception(); if (x.Value == "true" || x.Value == "false") { x.Type = TokenType.Bool; return x; } for (int i = 0; i <= 117; i++) if (x.Value == (((Opcode)i) == Opcode.new_ ? "new" : ((Opcode)i).ToString())) { x.Type = TokenType.Opcode; return x; } x.Type = TokenType.LabelValue; return x; } bool CheckLabelMark(Token x) { if (x.Type != TokenType.LabelMark) throw new Exception(); if (x.Value == "true" || x.Value == "false") return false; for (int i = 0; i <= 117; i++) if (x.Value == (((Opcode)i) == Opcode.new_ ? "new" : ((Opcode)i).ToString())) return false; return true; } uint CalcCodeSize(object x) { if (x == null) return 0; if (x is Mov) { Mov x_ = (Mov)x; uint y = 0 + 1; switch (x_.DestAddressing) { case Addressing.X: y += 1 + 1; break; case Addressing.HP: y += 1 + 0; break; case Addressing.Data: y += 1 + 4; break; case Addressing.Stack: y += 1 + 4; break; case Addressing.Heap: y += 1 + 1; break; } if (x_.SrcIsLabelValue) { y += 1 + 4; } else { switch (x_.SrcAddressing) { case Addressing.Immediate: switch (x_.TheOpcode) { case Opcode.mov1: y += 1 + 1; break; case Opcode.mov2: y += 1 + 2; break; case Opcode.mov4: y += 1 + 4; break; case Opcode.mov8: y += 1 + 8; break; } break; case Addressing.X: y += 1 + 1; break; case Addressing.HP: y += 1 + 0; break; case Addressing.Data: y += 1 + 4; break; case Addressing.Stack: y += 1 + 4; break; case Addressing.Heap: y += 1 + 1; break; } } return y; } else if (x is Other) { Other x_ = (Other)x; return (uint)(1 + x_.Xs.Length); } throw new Exception(); } } }