private ExpressionParserOutput ParseNumericExpression(string expression) { var nc = new NumericExpressionParser { Variables = Variables }; nc.Compile(expression, Output.StringCounter, Output.LoopCounter); Output.StringCounter = nc.Output.StringCounter; Output.LoopCounter = nc.Output.LoopCounter; Output.InitCode = Output.InitCode + nc.Output.InitCode; foreach (var f in nc.Output.Functions) { if (!Output.Functions.Contains(f)) { Output.Functions.Add(f); } } foreach (KeyValuePair <string, string> kvp in nc.Variables) { if (!Variables.ContainsKey(kvp.Key)) { Variables.Add(kvp.Key, kvp.Value); } } return(nc.Output); }
private void Factor(TokenParser parser) { if (_token == null) { return; } if (_token.TokenName == TokenParser.Tokens.LPAREN) { SkipWhiteSpace(parser); _token = parser.GetToken(); SkipWhiteSpace(parser); Expression(parser); if (_token == null) { return; } SkipWhiteSpace(parser); _token = parser.GetToken(); SkipWhiteSpace(parser); } else if (_token.TokenName == TokenParser.Tokens.LABEL || TokenParser.GetNumericFunctionsList().Contains(_token.TokenName)) { string name = _token.TokenValue.ToUpper().Trim(); bool isArray = false; _hasLabel = true; switch (_token.TokenName) { case TokenParser.Tokens.LEN: name = "LEN"; break; case TokenParser.Tokens.ASC: name = "ASC"; break; case TokenParser.Tokens.RND: name = "RND"; break; case TokenParser.Tokens.INSTR: name = "INSTR"; break; } SkipWhiteSpace(parser); if (parser.Peek() != null && parser.Peek().TokenPeek != null && (parser.Peek().TokenPeek.TokenName == TokenParser.Tokens.LPAREN) || TokenParser.GetNumericFunctionsList().Contains(_token.TokenName)) { if (Variables.ContainsKey("varArray" + name) && Variables["varArray" + name].StartsWith("varArray" + name + " rmb ")) { isArray = true; int paren = 1; string exp = ""; while (_token != null && paren >= 1) { var peek = parser.Peek(); if (peek != null && peek.TokenPeek != null && peek.TokenPeek.TokenValue != null) { if (peek.TokenPeek.TokenName == TokenParser.Tokens.LPAREN) { paren++; } if (peek.TokenPeek.TokenName == TokenParser.Tokens.RPAREN) { paren--; if (paren == 1) { SkipWhiteSpace(parser); parser.GetToken(); SkipWhiteSpace(parser); exp = exp + ")"; _token = parser.GetToken(); SkipWhiteSpace(parser); break; } } exp = exp + peek.TokenPeek.TokenValue; _token = parser.GetToken(); } else { break; } } var nc2 = new NumericExpressionParser { Variables = Variables }; nc2.Compile("(" + exp + ")", Output.StringCounter, Output.LoopCounter); Output.StringCounter = nc2.Output.StringCounter; Output.LoopCounter = nc2.Output.LoopCounter; Output.InitCode = Output.InitCode + nc2.Output.InitCode; foreach (KeyValuePair <string, string> kvp in nc2.Variables) { if (!Variables.ContainsKey(kvp.Key)) { Variables.Add(kvp.Key, kvp.Value); } } Output.Output = Output.Output + nc2.Output.Output; Output.Output = Output.Output + " tfr x,d" + Environment.NewLine; Output.Output = Output.Output + " tfr b,a" + Environment.NewLine; Output.Output = Output.Output + " ldx #varArray" + name + Environment.NewLine; Output.Output = Output.Output + " call ArrayIndexNumeric" + Environment.NewLine; Output.Output = Output.Output + " ldb ,x+" + Environment.NewLine; Output.Output = Output.Output + " lda ,x" + Environment.NewLine; Output.Output = Output.Output + " tfr d,x" + Environment.NewLine; } } if (!isArray && !TokenParser.GetNumericFunctionsList().Contains(_token.TokenName)) { _token = parser.GetToken(); } SkipWhiteSpace(parser); if (_token != null && (_token.TokenName == TokenParser.Tokens.LPAREN || TokenParser.GetNumericFunctionsList().Contains(_token.TokenName))) { if (_token.TokenName == TokenParser.Tokens.INSTR) { DoInstr(parser); SkipWhiteSpace(parser); _token = parser.GetToken(); return; } int paren = 1; string exp = ""; while (_token != null && paren > 0) { var peek = parser.Peek(); if (peek != null && peek.TokenPeek != null && peek.TokenPeek.TokenValue != null) { if (peek.TokenPeek.TokenName == TokenParser.Tokens.LPAREN) { paren++; } if (peek.TokenPeek.TokenName == TokenParser.Tokens.RPAREN) { paren--; if (paren == 0) { _token = parser.GetToken(); break; } } exp = exp + peek.TokenPeek.TokenValue; _token = parser.GetToken(); } else { break; } } IExpressionParser eParser = BooleanExpressionParser.IsString(exp) ? (IExpressionParser) new StringExpressionParser() : new NumericExpressionParser(); eParser.Variables = Variables; eParser.Compile(exp, Output.StringCounter, Output.LoopCounter); Output.StringCounter = eParser.Output.StringCounter; Output.LoopCounter = eParser.Output.LoopCounter; Output.InitCode = Output.InitCode + eParser.Output.InitCode; foreach (KeyValuePair <string, string> kvp in eParser.Variables) { if (!Variables.ContainsKey(kvp.Key)) { Variables.Add(kvp.Key, kvp.Value); } } //Output.Output = Output.Output + " push y" + Environment.NewLine; //if (BooleanExpressionParser.IsString(exp)) // Output.Output = Output.Output + " ldy #TheBasicStrBuf" + Environment.NewLine; //Output.Output = Output.Output + eParser.Output.Output; //if (BooleanExpressionParser.IsString(exp)) // Output.Output = Output.Output + " ldx #TheBasicStrBuf" + Environment.NewLine; //if (name.Trim().ToUpper() == "INPUT") // Output.Output = Output.Output + " call func" + name + "2" + Environment.NewLine; //else Output.Output = Output.Output + " call func" + name + Environment.NewLine; //Output.Output = Output.Output + " pop y" + Environment.NewLine; Output.Output = Output.Output + eParser.Output.Output; if (BooleanExpressionParser.IsString(exp)) { Output.Output = Output.Output + " push y" + Environment.NewLine; Output.Output = Output.Output + " push x" + Environment.NewLine; Output.Output = Output.Output + " call func" + name + Environment.NewLine; Output.Output = Output.Output + " tfr x,y" + Environment.NewLine; Output.Output = Output.Output + " pop x" + Environment.NewLine; Output.Output = Output.Output + " call freememory" + Environment.NewLine; Output.Output = Output.Output + " tfr y,x" + Environment.NewLine; Output.Output = Output.Output + " pop y" + Environment.NewLine; } else { Output.Output = Output.Output + " call func" + name + Environment.NewLine; } SkipWhiteSpace(parser); _token = parser.GetToken(); SkipWhiteSpace(parser); } else { if (!isArray) { Output.Output = Output.Output + " ldx var" + name + Environment.NewLine; } AddVariable("var" + name); } } else { if (_token.TokenName == TokenParser.Tokens.HEXNUMBER) { Output.Output = Output.Output + " ldx #$" + _token.TokenValue.Replace("&h", "").Replace("&H", "") + Environment.NewLine; } else { Output.Output = Output.Output + " ldx #" + _token.TokenValue + Environment.NewLine; } SkipWhiteSpace(parser); _token = parser.GetToken(); SkipWhiteSpace(parser); } }
private void DoInstr(TokenParser parser) { SkipWhiteSpace(parser); string exp1 = GetNumericExpression(parser, false); SkipWhiteSpace(parser); // Should be a comma parser.GetToken(); SkipWhiteSpace(parser); string exp2 = GetStringExpression(parser); SkipWhiteSpace(parser); // Should be a comma parser.GetToken(); SkipWhiteSpace(parser); string exp3 = GetStringExpression(parser).Trim(); //exp3 = exp3.Remove(exp3.Length - 1, 1); SkipWhiteSpace(parser); // Should be closing parenthesis parser.GetToken(); SkipWhiteSpace(parser); StringExpressionParser sourceString = new StringExpressionParser { Variables = Variables }; sourceString.Compile(exp2, Output.StringCounter, Output.LoopCounter); Output.StringCounter = sourceString.Output.StringCounter; Output.LoopCounter = sourceString.Output.LoopCounter; Output.BoolCounter = sourceString.Output.BoolCounter; Output.InitCode = Output.InitCode + sourceString.Output.InitCode; foreach (Functions f in sourceString.Output.Functions) { if (!Output.Functions.Contains(f)) { Output.Functions.Add(f); } } string param2Code = sourceString.Output.Output; StringExpressionParser destString = new StringExpressionParser { Variables = Variables }; destString.Compile(exp3, Output.StringCounter, Output.LoopCounter); Output.StringCounter = destString.Output.StringCounter; Output.LoopCounter = destString.Output.LoopCounter; Output.BoolCounter = destString.Output.BoolCounter; Output.InitCode = Output.InitCode + destString.Output.InitCode; foreach (Functions f in destString.Output.Functions) { if (!Output.Functions.Contains(f)) { Output.Functions.Add(f); } } string param3Code = destString.Output.Output; NumericExpressionParser startIndex = new NumericExpressionParser { Variables = Variables }; startIndex.Compile(exp1, Output.StringCounter, Output.LoopCounter); Output.StringCounter = startIndex.Output.StringCounter; Output.LoopCounter = startIndex.Output.LoopCounter; Output.BoolCounter = startIndex.Output.BoolCounter; Output.InitCode = Output.InitCode + startIndex.Output.InitCode; Output.Output = Output.Output + startIndex.Output.Output; Output.Output = Output.Output + " push x" + Environment.NewLine; Output.Output = Output.Output + param2Code; Output.Output = Output.Output + " push x" + Environment.NewLine; Output.Output = Output.Output + param3Code; Output.Output = Output.Output + " call funcINSTR" + Environment.NewLine; }
public void Compile(string expression, int stringCounter, int loopCounter) { var parser = new TokenParser(); ExpressionParserOutput output = new ExpressionParserOutput { StringCounter = stringCounter, LoopCounter = loopCounter }; Output = output; parser.InputString = expression; SkipWhiteSpace(parser); Token token = parser.GetToken(); while (token != null && token.TokenName != TokenParser.Tokens.NEWLINE) { SkipWhiteSpace(parser); if (token.TokenName == TokenParser.Tokens.STRING) { if (token.TokenValue == "\"\"") { Output.InitCode = Output.InitCode + "st" + Output.StringCounter + " chr 0" + Environment.NewLine; } else { Output.InitCode = Output.InitCode + "st" + Output.StringCounter + " str " + token.TokenValue + Environment.NewLine; Output.InitCode = Output.InitCode + " chr 0" + Environment.NewLine; } Output.Output = Output.Output + " ldx #st" + Output.StringCounter + Environment.NewLine; Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine; Output.Output = Output.Output + " cmpa #0" + Environment.NewLine; Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + " sta ,y+" + Environment.NewLine; Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" + Environment.NewLine; Output.LoopCounter++; Output.StringCounter++; } if (token.TokenName == TokenParser.Tokens.PLUS) { //token = parser.GetToken(); //continue; } if (token.TokenName == TokenParser.Tokens.STRINGLABEL) { string varName = token.TokenValue.Replace("$", "").ToUpper(); SkipWhiteSpace(parser); if (parser.Peek() != null && parser.Peek().TokenPeek != null && parser.Peek().TokenPeek.TokenName == TokenParser.Tokens.LPAREN) { parser.GetToken(); SkipWhiteSpace(parser); string exp = GetNumericExpression(parser); var nc = new NumericExpressionParser { Variables = Variables }; nc.Compile(exp, Output.StringCounter, Output.LoopCounter); Output.StringCounter = nc.Output.StringCounter; Output.LoopCounter = nc.Output.LoopCounter; foreach (var f in nc.Output.Functions) { AddFunction(f); } string ndxCode = nc.Output.Output; Output.Output = Output.Output + ndxCode; Output.Output = Output.Output + " tfr x,d" + Environment.NewLine; Output.Output = Output.Output + " tfr b,a" + Environment.NewLine; Output.Output = Output.Output + " ldx #varStrArray" + varName + Environment.NewLine; Output.Output = Output.Output + " call ArrayIndexString" + Environment.NewLine; Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine; Output.Output = Output.Output + " cmpa #0" + Environment.NewLine; Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + " sta ,y+" + Environment.NewLine; Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" + Environment.NewLine; Output.LoopCounter++; } else { Output.Output = Output.Output + " ldx #varStr" + varName + Environment.NewLine; Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine; Output.Output = Output.Output + " cmpa #0" + Environment.NewLine; Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + " sta ,y+" + Environment.NewLine; Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" + Environment.NewLine; Output.LoopCounter++; } } if (token.TokenName == TokenParser.Tokens.UCASE) { string exp = GetStringExpression(parser); ExpressionParserOutput o = ParseStringExpression(exp); AddFunction(Functions.FuncUcase); Output.Output = Output.Output + " push y" + Environment.NewLine; Output.Output = Output.Output + o.Output; Output.Output = Output.Output + " pop y" + Environment.NewLine; Output.Output = Output.Output + " call funcUCASE" + Environment.NewLine; } if (token.TokenName == TokenParser.Tokens.LCASE) { string exp = GetStringExpression(parser); ExpressionParserOutput o = ParseStringExpression(exp); AddFunction(Functions.FuncLcase); Output.Output = Output.Output + " push y" + Environment.NewLine; Output.Output = Output.Output + o.Output; Output.Output = Output.Output + " pop y" + Environment.NewLine; Output.Output = Output.Output + " call funcLCASE" + Environment.NewLine; } if (token.TokenName == TokenParser.Tokens.INPUT) { SkipWhiteSpace(parser); // Should be a left parenthesis parser.GetToken(); // Should be a right parenthesis parser.GetToken(); Output.Output = Output.Output + " call funcINPUT" + Environment.NewLine; Output.Output = Output.Output + " ldx #InputBuffer" + Environment.NewLine; Output.Output = Output.Output + "loop" + Output.LoopCounter + " lda ,x+" + Environment.NewLine; Output.Output = Output.Output + " cmpa #0" + Environment.NewLine; Output.Output = Output.Output + " jeq exitLoop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + " sta ,y+" + Environment.NewLine; Output.Output = Output.Output + " jmp loop" + Output.LoopCounter + Environment.NewLine; Output.Output = Output.Output + "exitLoop" + Output.LoopCounter + " sta ,y" + Environment.NewLine; Output.LoopCounter++; AddFunction(Functions.FuncInput); AddFunction(Functions.FuncPrint); } if (token.TokenName == TokenParser.Tokens.CHR) { SkipWhiteSpace(parser); // Should be a left parenthesis parser.GetToken(); string exp = GetNumericExpression(parser); ExpressionParserOutput o = ParseNumericExpression(exp); SkipWhiteSpace(parser); // Should be a right parenthesis parser.GetToken(); SkipWhiteSpace(parser); Output.Output = Output.Output + o.Output; Output.Output = Output.Output + " tfr x,d" + Environment.NewLine; Output.Output = Output.Output + " stb ,y+" + Environment.NewLine; Output.Output = Output.Output + " sta ,y" + Environment.NewLine; } if (token.TokenName == TokenParser.Tokens.MID) { string exp = GetStringExpression(parser); ExpressionParserOutput o = ParseStringExpression(exp); SkipWhiteSpace(parser); // Should be a comma parser.GetToken(); SkipWhiteSpace(parser); Output.Output = Output.Output + " push y" + Environment.NewLine; Output.Output = Output.Output + o.Output; Output.Output = Output.Output + " pop y" + Environment.NewLine; exp = GetNumericExpression(parser); o = ParseNumericExpression(exp); SkipWhiteSpace(parser); // Should be a comma parser.GetToken(); SkipWhiteSpace(parser); Output.Output = Output.Output + "" + Environment.NewLine; Output.Output = Output.Output + o.Output; Output.Output = Output.Output + " tfr x,d" + Environment.NewLine; Output.Output = Output.Output + " push d" + Environment.NewLine; exp = GetNumericExpression(parser); o = ParseNumericExpression(exp); SkipWhiteSpace(parser); Output.Output = Output.Output + o.Output; Output.Output = Output.Output + " pop d" + Environment.NewLine; Output.Output = Output.Output + " call funcMID" + Environment.NewLine; AddFunction(Functions.FuncMid); } token = parser.GetToken(); } }