private static bool isKeyWordOrProcName(Token t) { return(t.Type == TknType.Word && (Syntax.IsKeyWord(t.Text) || defProcs.Contains(t.Text))); }
/// <summary> Proc calls or keywords </summary> private static int readNextExpr(ref List <Token> ts, ref List <byte> bytes, ref List <string> vars, int i) { int argCount = 0; //[cmd] [ [ops | null] args | null] //Need command or newline: if (ts[i].Type == TknType.NewLine || Syntax.IsEnumOperator(ts[i])) { return(i + 1); } if (ts[i].Type != TknType.Word) { new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.UndefinedCommand, ts[i].Text); } // string cmd = ts[i].Text; i++; //to args if (IsProcessName(cmd)) { //push args: while (!isKeyWordOrProcName(ts[i]) && !Syntax.IsTokenHasOperator(ts[i], Syntax.OP_END)) { bytes.AddRange(pushArg(ts[i], ref vars, inFile(ref ts, i), inLine(ref ts, i))); i++; } //call proc: bytes.AddCmd(CmdType.RUN_ID, (uint)getProcID(cmd)); } else { switch (cmd) { //new var case Syntax.KW_BYTE: while (!isKeyWordOrProcName(ts[i])) { if (Syntax.IsEnumOperator(ts[i]) || ts[i].Type == TknType.NewLine) { i++; continue; } if (ts[i].Type != TknType.Word) { new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.InvalidArgument, $"'{ts[i].Text}' for {cmd}"); } if (!vars.Contains(ts[i].Text)) { vars.Add(ts[i].Text); } bytes.AddCmd(CmdType.BYTE_I, (uint)getVarID(ref vars, ts[i].Text)); i++; } break; //var or value case Syntax.KW_ADD: i = readCmd(CmdType.ADD_V, CmdType.ADD_I, cmd, ref ts, ref bytes, ref vars, i); break; case Syntax.KW_DIVIDE: i = readCmd(CmdType.DIV_V, CmdType.DIV_I, cmd, ref ts, ref bytes, ref vars, i); break; case Syntax.KW_IS: i = readCmd(CmdType.IS_V, CmdType.IS_I, cmd, ref ts, ref bytes, ref vars, i); break; case Syntax.KW_MODULE: i = readCmd(CmdType.MOD_C, CmdType.MOD_B, cmd, ref ts, ref bytes, ref vars, i); break; case Syntax.KW_MULTIPLY: i = readCmd(CmdType.MUL_V, CmdType.MUL_I, cmd, ref ts, ref bytes, ref vars, i); break; case Syntax.KW_PUSH: i = readCmd(CmdType.PUSH_V, CmdType.PUSH_I, cmd, ref ts, ref bytes, ref vars, i); break; case Syntax.KW_SUBTRACT: i = readCmd(CmdType.SUB_V, CmdType.SUB_I, cmd, ref ts, ref bytes, ref vars, i); break; //roots case Syntax.KW_IF: i = readIf(ref ts, ref bytes, ref vars, i); break; case Syntax.KW_WHILE: i = readWhile(ref ts, ref bytes, ref vars, i); break; //var only case Syntax.KW_THIS: i = readVarArgOnlyCmd(CmdType.THIS_I, cmd, ref ts, ref bytes, ref vars, i, ref argCount); break; case Syntax.KW_POP: i = readVarArgOnlyCmd(CmdType.POP_I, cmd, ref ts, ref bytes, ref vars, i, ref argCount); if (argCount == 0) { bytes.AddCmd(CmdType.POP); } break; case Syntax.KW_PEEK: i = readVarArgOnlyCmd(CmdType.PEEK_B, cmd, ref ts, ref bytes, ref vars, i, ref argCount); break; case Syntax.KW_DECREMENT: i = readVarArgOnlyCmd(CmdType.DEC_B, cmd, ref ts, ref bytes, ref vars, i, ref argCount); break; case Syntax.KW_INCREMENT: i = readVarArgOnlyCmd(CmdType.INC_B, cmd, ref ts, ref bytes, ref vars, i, ref argCount); break; case Syntax.KW_NOT: i = readVarArgOnlyCmd(CmdType.NOT_B, cmd, ref ts, ref bytes, ref vars, i, ref argCount); break; case Syntax.KW_INPUT: i = readVarArgOnlyCmd(CmdType.INPUT_B, cmd, ref ts, ref bytes, ref vars, i, ref argCount); if (argCount == 0) { bytes.AddCmd(CmdType.INPUT); } break; //var or 3 value case Syntax.KW_OUTPUT: i = readOutput(CmdType.SUB_V, CmdType.SUB_I, cmd, ref ts, ref bytes, ref vars, i); break; //null case Syntax.KW_FLIP: bytes.AddCmd(CmdType.FLIP); break; case Syntax.KW_STOP: bytes.AddCmd(CmdType.PRC_STP); break; case Syntax.KW_OUTCLEAR: bytes.AddCmd(CmdType.CLR_OUT); break; case Syntax.KW_STACLEAR: bytes.AddCmd(CmdType.CLR_STK); break; case Syntax.KW_PUSH_THIS: bytes.AddCmd(CmdType.PUSH_T); break; case Syntax.KW_POP_THIS: bytes.AddCmd(CmdType.POP_T); break; // default: new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.UndefinedCommand, cmd); break; } } Console.Write($"\r{(int)((float)i * 100.0 / ts.Count)}%"); return(i); }
private static int readIf(ref List <Token> ts, ref List <byte> bytes, ref List <string> vars, int i) { //if [var | has | pop | const] { ... } //ARGUMENT: Token arg = ts[i]; switch (arg.Type) { case TknType.Number: bytes.AddCmd(CmdType.IF_C, toByte(arg.Text, inFile(ref ts, i), inLine(ref ts, i))); break; case TknType.Char: bytes.AddCmd(CmdType.IF_C, (byte)arg.Text[0]); break; case TknType.Word: switch (arg.Text) { case Syntax.OP_HAS: bytes.AddCmd(CmdType.IF_HAS); break; case Syntax.KW_POP: bytes.AddCmd(CmdType.IF_POP); break; default: if (!vars.Contains(arg.Text)) { new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.UndefinedVariable, arg.Text); } bytes.AddCmd(CmdType.IF_B, (uint)getVarID(ref vars, arg.Text)); break; } break; default: new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.InvalidArgument, $"'{arg.Text}' for if"); break; } //SEEK BODY ('{'): i++; while (!Syntax.IsTokenHasOperator(ts[i], Syntax.OP_BEGIN)) { if (ts[i].Type != TknType.NewLine) { new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.UndefinedBody, "if"); } i++; } //READ BODY: i = readNextBody(ref ts, ref bytes, ref vars, i) + 1; //SEEK ELSE: while (!Syntax.IsTokenHasKeyWord(ts[i], Syntax.KW_ELSE)) { if (ts[i].Type != TknType.NewLine) { break; } i++; } //IS ELSE? if (Syntax.IsTokenHasKeyWord(ts[i], Syntax.KW_ELSE)) { bytes.AddCmd(CmdType.IF_ELSE); //SEEK ELSE BODY ('{'): i++; while (!Syntax.IsTokenHasOperator(ts[i], Syntax.OP_BEGIN)) { if (ts[i].Type != TknType.NewLine) { new CompileException(inFile(ref ts, i), inLine(ref ts, i), ErrCode.UndefinedBody, "else"); } i++; } //READ ELSE BODY: i = readNextBody(ref ts, ref bytes, ref vars, i) + 1; } //END: bytes.AddCmd(CmdType.IF_END); return(i); }
private static void seekProcDefs(ref List <Token> ts) { defProcs = new List <string>(); int L = 1; string F = "[not found]"; int lvl = 0; for (int i = 0; i < ts.Count; i++) { if (Syntax.IsTokenHasKeyWord(ts[i], Syntax.KW_PROCESS)) { if (lvl != 0) { new CompileException(F, L, ErrCode.ProcInProc); } i++; if (ts[i].Type != TknType.Word) { new CompileException(F, L, ErrCode.ProcNameNotFound); } if (!Syntax.IsKeyWord(ts[i].Text)) { addUniqueProcName(ts[i].Text); } else { new CompileException(F, L, ErrCode.KeyProc, ts[i].Text); } //skip args... i = seekProcBodies(i, ref ts, F, ref L); } else { if (ts[i].Type != TknType.FilePtr && ts[i].Type != TknType.NewLine && lvl == 0) { new CompileException(F, L, ErrCode.BadTokenArea, ts[i].Text); } } if (ts[i].Type == TknType.Operator) { if (ts[i].Text == Syntax.OP_BEGIN) { lvl++; } if (ts[i].Text == Syntax.OP_END) { lvl--; } } if (ts[i].Type == TknType.FilePtr) { F = ts[i].Text; L = 1; } L += ts[i].Type == TknType.NewLine ? 1 : 0; } }