amath/src/main/parser.cpp

789 lines
17 KiB
C++
Raw Normal View History

2017-02-27 22:23:06 +00:00
/*-
2021-01-11 19:37:42 +00:00
* Copyright (c) 2014-2021 Carsten Sonne Larsen <cs@innolan.net>
2015-04-01 12:43:50 +00:00
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
2017-02-27 22:23:06 +00:00
* Project homepage:
2017-07-14 09:30:24 +00:00
* https://amath.innolan.net
2021-01-11 19:37:42 +00:00
*
2015-04-01 12:43:50 +00:00
*/
2017-02-27 22:23:06 +00:00
#include "amath.h"
#include "amathc.h"
#include "parser.h"
#include "values.h"
#include "operators.h"
#include "statements.h"
#include "userfunction.h"
2015-04-01 12:43:50 +00:00
#include "lib/numb.h"
#include "lib/cplex.h"
2017-04-12 22:50:51 +00:00
#include "lib/ntextd.h"
#include "loc/text.h"
2015-04-01 12:43:50 +00:00
#include "system/program.h"
2017-02-27 22:23:06 +00:00
Parser::Parser(const char* input)
2015-04-01 12:43:50 +00:00
{
lexer = new Lexer(input);
2017-02-27 22:23:06 +00:00
token = nullptr;
errorNode = nullptr;
syntaxError = 0;
2021-01-14 23:01:10 +00:00
ResultOnly = false;
2015-04-01 12:43:50 +00:00
}
Parser::~Parser()
{
delete lexer;
}
SyntaxNode* Parser::Parse()
{
lexer->Tokenize();
2017-02-27 22:23:06 +00:00
token = nullptr;
2015-04-01 12:43:50 +00:00
2017-02-27 22:23:06 +00:00
StatementBlockNode* block = nullptr;
SyntaxNode* result;
Token* current;
2015-04-01 12:43:50 +00:00
2017-02-27 22:23:06 +00:00
do
{
2015-04-01 12:43:50 +00:00
result = TryParseStatement();
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symdelimiter || (token->symbol == symend && block != nullptr))
{
if (block == nullptr)
{
2015-04-01 12:43:50 +00:00
block = new StatementBlockNode();
}
2017-02-27 22:23:06 +00:00
if (result != nullptr)
{
2015-04-01 12:43:50 +00:00
block->Add(result);
}
2017-02-27 22:23:06 +00:00
while (token->symbol == symdelimiter)
{
2015-04-01 12:43:50 +00:00
GetToken();
}
2017-02-27 22:23:06 +00:00
}
else if (token->symbol != symend)
{
if (result != nullptr)
{
2015-04-01 12:43:50 +00:00
delete result;
}
2017-02-27 22:23:06 +00:00
if (block == nullptr)
{
2017-01-28 21:04:35 +00:00
block = new StatementBlockNode();
2015-04-01 12:43:50 +00:00
}
2017-01-28 21:04:35 +00:00
result = new ErrorNode(lexer->GetInput(), token->GetPos());
block->Add(result);
// Skip until next statement
2017-02-27 22:23:06 +00:00
do
{
2017-01-28 21:04:35 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
}
while (token->symbol != symdelimiter && token->symbol != symend);
2015-04-01 12:43:50 +00:00
}
current = token;
PutToken();
2017-02-27 22:23:06 +00:00
}
while (current->symbol != symend);
if (block != nullptr)
return block;
2015-04-01 12:43:50 +00:00
2017-02-27 22:23:06 +00:00
if (result == nullptr)
return new EmptyStatement();
return result;;
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::TryParseStatement()
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symend || token->symbol == symdelimiter)
{
2015-04-01 12:43:50 +00:00
PutToken();
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
PutToken();
2017-02-27 22:23:06 +00:00
errorNode = nullptr;
2015-04-01 12:43:50 +00:00
syntaxError = -1;
2017-02-27 22:23:06 +00:00
SyntaxNode* result = ParseStatement();
2015-04-01 12:43:50 +00:00
2017-02-27 22:23:06 +00:00
if (errorNode == nullptr && syntaxError != -1)
{
2015-04-01 12:43:50 +00:00
errorNode = new ErrorNode(lexer->GetInput(), syntaxError);
}
2017-02-27 22:23:06 +00:00
if (errorNode != nullptr)
{
2015-04-01 12:43:50 +00:00
delete result;
result = errorNode;
}
return result;
}
// -----------------------------------------------------
// -------------- Recursive-descent logic --------------
// -----------------------------------------------------
SyntaxNode* Parser::ParseStatement()
{
2017-02-27 22:23:06 +00:00
SyntaxNode* res;
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
switch (token->symbol)
{
2015-04-01 12:43:50 +00:00
case symhelp:
res = ParseHelpStatement();
break;
case symdelete:
res = ParseDeleteStatement();
break;
case symdef:
res = ParseFunctionDef();
break;
2017-03-11 22:37:45 +00:00
#if defined(UNIX) || defined(HAIKU) || defined(AMIGA)
2015-04-01 12:43:50 +00:00
case symlist:
res = ParseListStatement();
break;
2017-02-27 22:23:06 +00:00
#endif
2015-04-01 12:43:50 +00:00
case symshow:
case symload:
case symsave:
case symexecute:
res = ParseFileStatement();
break;
case syminput:
case symoutput:
res = ParseNumeralStatement();
break;
case symprompt:
res = ParsePromptStatement();
break;
case symprefs:
res = ParsePrefsStatement();
break;
case symdigits:
res = ParseDigistStatement();
break;
case symdraw:
case symplot:
res = ParseDrawStatement();
break;
2017-02-27 22:23:06 +00:00
case symabout:
res = new AboutStatement();
break;
case symlicense:
res = new LicenseStatement();
break;
2015-04-01 12:43:50 +00:00
case symversion:
res = new VersionStatement();
break;
2017-02-27 22:23:06 +00:00
case symexit:
2015-04-01 12:43:50 +00:00
res = new ExitStatement();
break;
2017-04-15 20:33:46 +00:00
#if defined(AMIGA) || defined(TERMIOS) || defined(WINDOWS)
2015-04-01 12:43:50 +00:00
case symclear:
2017-02-27 22:23:06 +00:00
res = new ClearStatement();
2015-04-01 12:43:50 +00:00
break;
2017-02-27 22:23:06 +00:00
#endif
2015-04-01 12:43:50 +00:00
case symmem:
res = new MemoryStatement();
break;
2017-02-27 22:23:06 +00:00
case symvariable:
2015-04-01 12:43:50 +00:00
res = new ListVariablesStatement();
break;
case symfunction:
res = new ListFunctionsStatement();
break;
case symeval:
2021-01-14 23:01:10 +00:00
res = new EvalStatement(ParseExpression(), ResultOnly);
2015-04-01 12:43:50 +00:00
break;
default:
PutToken();
res = ParseDefault();
}
return res;
}
SyntaxNode* Parser::ParseDefault()
{
2017-02-27 22:23:06 +00:00
Token* temp = token;
2015-04-01 12:43:50 +00:00
// Peek tokens
bool funcdef = Expect(symident);
funcdef = funcdef && Expect(symlparen);
funcdef = funcdef && Expect(symident);
funcdef = funcdef && Expect(symrparen);
funcdef = funcdef && Expect(symassign);
// Restart parsing
syntaxError = -1;
2017-02-27 22:23:06 +00:00
errorNode = nullptr;
2015-04-01 12:43:50 +00:00
token = temp;
2017-02-27 22:23:06 +00:00
if (funcdef)
{
2015-04-01 12:43:50 +00:00
return ParseFunctionDef();
}
2017-02-27 22:23:06 +00:00
return ParseEvaluation();
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParseEvaluation()
{
2017-02-27 22:23:06 +00:00
ExpressionNode* exp = ParseExpression();
if (exp == nullptr)
{
return nullptr;
2015-04-01 12:43:50 +00:00
}
2021-01-14 23:01:10 +00:00
StatementNode* sta = new EvalStatement(exp, ResultOnly);
2017-02-27 22:23:06 +00:00
if (exp->IsSilent())
{
2015-04-01 12:43:50 +00:00
sta = new SilentStatement(sta);
}
return sta;
}
2017-02-27 22:23:06 +00:00
ExpressionNode* Parser::ParseExpression()
2015-04-01 12:43:50 +00:00
{
return ParseAddSubstract();
}
2017-02-27 22:23:06 +00:00
ExpressionNode* Parser::ParseAddSubstract()
2015-04-01 12:43:50 +00:00
{
2017-02-27 22:23:06 +00:00
ExpressionNode* node = ParseFactor();
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
while (token->symbol == symplus || token->symbol == symminus)
{
if (token->symbol == symplus)
{
node = new AdditionNode(node, ParseFactor());
}
else if (token->symbol == symminus)
{
node = new SubtractionNode(node, ParseFactor());
2015-04-01 12:43:50 +00:00
}
GetToken();
}
PutToken();
return node;
}
2017-02-27 22:23:06 +00:00
ExpressionNode* Parser::ParseFactor()
2015-04-01 12:43:50 +00:00
{
2017-02-27 22:23:06 +00:00
ExpressionNode* node = ParsePower();
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
while (token->symbol == symtimes || token->symbol == symslash)
{
if (token->symbol == symtimes)
{
node = new MultiplicationNode(node, ParsePower());
}
else if (token->symbol == symslash)
{
node = new DivisionNode(node, ParsePower());
2015-04-01 12:43:50 +00:00
}
GetToken();
}
PutToken();
return node;
}
ExpressionNode* Parser::ParsePower()
{
2017-02-27 22:23:06 +00:00
ExpressionNode* node = ParseUnary();
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
while (token->symbol == sympower)
{
node = new PowerNode(node, ParseUnary());
GetToken();
2015-04-01 12:43:50 +00:00
}
PutToken();
return node;
}
ExpressionNode* Parser::ParseUnary()
{
ExpressionNode* node;
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symminus)
{
node = new UnaryNode(ParseAtomic());
}
else
{
2015-04-01 12:43:50 +00:00
PutToken();
node = ParseAtomic();
}
return node;
}
2017-02-27 22:23:06 +00:00
ExpressionNode* Parser::ParseAtomic()
2015-04-01 12:43:50 +00:00
{
ExpressionNode* node;
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symlparen)
{
2015-04-01 12:43:50 +00:00
node = ParseExpression();
Expect(symrparen);
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == symabsolute)
{
2015-04-01 12:43:50 +00:00
node = new AbsoluteNode(ParseExpression());
Expect(symabsolute);
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == symident)
{
2015-04-01 12:43:50 +00:00
node = ParseIdent();
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == sympi)
{
2015-04-01 12:43:50 +00:00
node = new PiNode();
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == syme)
{
2015-04-01 12:43:50 +00:00
node = new EulersNumberNode();
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == symi)
{
2015-04-01 12:43:50 +00:00
node = new ComplexiNode();
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == symins)
{
2015-04-01 12:43:50 +00:00
node = new InsVariableNode();
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == symnumber)
{
2015-04-01 12:43:50 +00:00
node = ParseNumber();
2017-02-27 22:23:06 +00:00
}
else
{
2015-04-01 12:43:50 +00:00
node = new NumericValueNode();
syntaxError = token->GetPos();
}
2017-02-27 22:23:06 +00:00
if (Peek()->symbol == symfactorial)
{
GetToken();
node = new FactorialNode(node);
}
2015-04-01 12:43:50 +00:00
return node;
}
ExpressionNode* Parser::ParseIdent()
{
2017-02-27 22:23:06 +00:00
ExpressionNode* node;
Token* identToken = token;
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symlparen)
{
2015-04-01 12:43:50 +00:00
ExpressionNode* parameter = ParseExpression();
Expect(symrparen);
node = Program->Functions->GetFunctionCall(identToken->GetText(), parameter);
2017-02-27 22:23:06 +00:00
if (node == nullptr)
{
2015-04-01 12:43:50 +00:00
errorNode = new ErrorNode(
lexer->GetInput(),
HELPFUNNDEF,
identToken->GetText(),
identToken->GetPos());
delete parameter;
node = new NumericValueNode();
}
2017-02-27 22:23:06 +00:00
}
else if (token->symbol == symassign)
{
2015-04-01 12:43:50 +00:00
Variable* var = Program->Variables->CreateVariable(identToken->GetText());
node = new AssignmentNode(new VariableNode(var), ParseExpression());
2017-02-27 22:23:06 +00:00
}
else
{
2015-04-01 12:43:50 +00:00
PutToken();
Variable* var = Program->Variables->GetVariable(token->GetText());
2017-02-27 22:23:06 +00:00
if (var == nullptr)
{
2015-04-01 12:43:50 +00:00
errorNode = new ErrorNode(
lexer->GetInput(),
HELPVARNDEF,
identToken->GetText(),
identToken->GetPos());
node = new NumericValueNode();
2017-02-27 22:23:06 +00:00
}
else
{
2015-04-01 12:43:50 +00:00
node = new VariableNode(var);
}
}
return node;
}
ExpressionNode* Parser::ParseNumber()
{
2017-02-27 22:23:06 +00:00
const char* a = token->GetText();
Number* number;
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symi)
{
Number* imag = Program->Input->Parse(a);
2015-04-01 12:43:50 +00:00
number = new ComplexNumber(0.0, imag->GetRealValue());
delete imag;
2017-02-27 22:23:06 +00:00
}
else
{
2015-04-01 12:43:50 +00:00
PutToken();
number = Program->Input->Parse(a);
}
2017-02-27 22:23:06 +00:00
return new NumericValueNode(number);
2015-04-01 12:43:50 +00:00
}
// -----------------------------------------------------
// ------------------- Token logic ---------------------
// -----------------------------------------------------
2017-02-27 22:23:06 +00:00
void Parser::GetToken()
2015-04-01 12:43:50 +00:00
{
2017-02-27 22:23:06 +00:00
if (token == nullptr)
{
token = lexer->GetFirstToken();
}
else
{
token = token->GetNextToken();
}
}
Token* Parser::Peek() const
{
if (token == nullptr)
return lexer->GetFirstToken();
return token->GetNextToken();
2015-04-01 12:43:50 +00:00
}
void Parser::PutToken()
{
token = token->GetLastToken();
}
bool Parser::Expect(Symbol symbol)
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol != symbol)
{
2015-04-01 12:43:50 +00:00
syntaxError = token->GetPos();
return false;
}
2017-02-27 22:23:06 +00:00
return true;
2015-04-01 12:43:50 +00:00
}
// -----------------------------------------------------
// ----------------- Statement logic -------------------
// -----------------------------------------------------
SyntaxNode* Parser::ParseFunctionDef()
{
Expect(symident);
Token* funcToken = token;
Expect(symlparen);
Expect(symident);
Token* funcVariable = token;
Expect(symrparen);
Expect(symassign);
2017-02-27 22:23:06 +00:00
if (Program->Functions->IsSystemFunction(funcToken->GetText()))
{
2015-04-01 12:43:50 +00:00
errorNode = new ErrorNode(
lexer->GetInput(),
HELPFUNRDEF,
funcToken->GetText(),
funcToken->GetPos());
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
UserFunction* function = Program->Functions->GetFunctionDef(funcToken->GetText());
Variable* variable = function->CreateVariable(funcVariable->GetText());
Program->Variables->InsertTemporaryVariable(variable);
function->SetExpression(ParseExpression());
Program->Variables->RemoveTemporaryVariable();
// TODO: Move logic to FunctionDefinitionNode
return new FunctionDefinitionNode();
}
SyntaxNode* Parser::ParseHelpStatement()
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symdelimiter || token->symbol == symend)
{
2015-04-01 12:43:50 +00:00
PutToken();
return new HelpStatement();
}
2017-02-27 22:23:06 +00:00
if (token->symbol == symident)
return new HelpStatement(token->GetText());
return new HelpStatement(token->symbol);
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParseDeleteStatement()
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symvariable || token->symbol == symfunction)
{
2015-04-01 12:43:50 +00:00
return new DeleteStatement(token->symbol);
2017-02-27 22:23:06 +00:00
}
if (token->symbol != symident)
{
2015-04-01 12:43:50 +00:00
syntaxError = token->GetPos();
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
2017-02-27 22:23:06 +00:00
Token* identToken = token;
2015-04-01 12:43:50 +00:00
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symlparen)
{
2015-04-01 12:43:50 +00:00
Expect(symident);
2017-02-27 22:23:06 +00:00
Token* parameter = token;
2015-04-01 12:43:50 +00:00
Expect(symrparen);
return new DeleteStatement(identToken->GetText(), parameter->GetText());
}
2017-02-27 22:23:06 +00:00
PutToken();
return new DeleteStatement(token->GetText());
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParseListStatement()
{
GetToken();
if (token->symbol == symqident)
return new ListStatement(token->GetText());
2017-02-27 22:23:06 +00:00
if (token->symbol == symend || token->symbol == symdelimiter)
{
2015-04-01 12:43:50 +00:00
PutToken();
return new ListStatement();
}
2017-02-27 22:23:06 +00:00
syntaxError = token->GetPos();
return nullptr;
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParseFileStatement()
{
2017-02-27 22:23:06 +00:00
Token* statement = token;
2015-04-01 12:43:50 +00:00
Expect(symqident);
2017-02-27 22:23:06 +00:00
Token* identToken = token;
2015-04-01 12:43:50 +00:00
2017-02-27 22:23:06 +00:00
if (statement->symbol == symload)
2015-04-01 12:43:50 +00:00
return new LoadStatement(identToken->GetText());
2017-02-27 22:23:06 +00:00
if (statement->symbol == symsave)
2015-04-01 12:43:50 +00:00
return new SaveStatement(identToken->GetText());
2017-02-27 22:23:06 +00:00
if (statement->symbol == symexecute)
2015-04-01 12:43:50 +00:00
return new ExecuteStatement(identToken->GetText());
2017-02-27 22:23:06 +00:00
if (statement->symbol == symshow)
2015-04-01 12:43:50 +00:00
return new ShowStatement(identToken->GetText());
2017-02-27 22:23:06 +00:00
return new ErrorNode(
lexer->GetInput(),
HELPUERROR, EMPTYSTRING,
statement->GetPos());
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParseNumeralStatement()
{
2017-02-27 22:23:06 +00:00
Token* statement = token;
2015-04-01 12:43:50 +00:00
unsigned int base;
GetToken();
2017-02-27 22:23:06 +00:00
switch (token->symbol)
{
2015-04-01 12:43:50 +00:00
case symend:
2015-04-08 10:59:08 +00:00
case symdelimiter:
2015-04-01 12:43:50 +00:00
PutToken();
2017-02-27 22:23:06 +00:00
return (statement->symbol == syminput)
? static_cast<SyntaxNode*>(new InputStatement())
: static_cast<SyntaxNode*>(new OutputStatement());
2015-04-01 12:43:50 +00:00
case symbin:
base = 2;
break;
case symoct:
base = 8;
break;
case symdec:
base = 10;
break;
case symhex:
base = 16;
break;
default:
base = 0;
}
2017-02-27 22:23:06 +00:00
if (base == 0 && token->symbol != symnumber)
{
2015-04-01 12:43:50 +00:00
syntaxError = token->GetPos();
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
2017-02-27 22:23:06 +00:00
if (base == 0)
{
NumeralSystem* nsys = new DecimalSystem(0);
Number* number = nsys->Parse(token->GetText());
2015-04-01 12:43:50 +00:00
base = number->GetIntegerValue();
delete number;
delete nsys;
2017-02-27 22:23:06 +00:00
if (base < 2 || base > 32)
{
2015-04-01 12:43:50 +00:00
errorNode = new ErrorNode(
lexer->GetInput(),
HELPPNUMERA,
token->GetText(),
token->GetPos());
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
}
2017-02-27 22:23:06 +00:00
return (statement->symbol == syminput)
? static_cast<SyntaxNode*>(new InputStatement(base))
: static_cast<SyntaxNode*>(new OutputStatement(base));
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParseDigistStatement()
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symdelimiter || token->symbol == symend)
{
2015-04-01 12:43:50 +00:00
PutToken();
return new DigitsStatement();
2017-02-27 22:23:06 +00:00
}
if (token->symbol != symnumber)
{
2015-04-01 12:43:50 +00:00
syntaxError = token->GetPos();
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
2017-02-27 22:23:06 +00:00
NumeralSystem* nsys = new DecimalSystem(0);
Number* number = nsys->Parse(token->GetText());
2015-04-01 12:43:50 +00:00
int digits = number->GetIntegerValue();
delete number;
delete nsys;
2017-02-27 22:23:06 +00:00
if (digits < 0 || digits > 15)
{
2015-04-01 12:43:50 +00:00
errorNode = new ErrorNode(
lexer->GetInput(),
HELPPDIGITS,
token->GetText(),
token->GetPos());
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
return new DigitsStatement(digits);
}
SyntaxNode* Parser::ParsePromptStatement()
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symqident)
{
2015-04-01 12:43:50 +00:00
return new PromptStatement(token->GetText());
}
PutToken();
2017-02-27 22:23:06 +00:00
return nullptr;
2015-04-01 12:43:50 +00:00
}
SyntaxNode* Parser::ParsePrefsStatement()
{
GetToken();
2017-02-27 22:23:06 +00:00
if (token->symbol == symload || token->symbol == symsave)
{
2015-04-01 12:43:50 +00:00
return new PrefsStatement(token->symbol);
}
PutToken();
return new PrefsStatement();;
}
SyntaxNode* Parser::ParseDrawStatement()
{
2017-02-27 22:23:06 +00:00
Token* statement = token;
2015-04-01 12:43:50 +00:00
Expect(symident);
2017-02-27 22:23:06 +00:00
Token* identToken = token;
2015-04-01 12:43:50 +00:00
Expect(symlparen);
Expect(symident);
2017-02-27 22:23:06 +00:00
Token* paramToken = token;
2015-04-01 12:43:50 +00:00
Expect(symrparen);
2017-02-27 22:23:06 +00:00
if (statement->symbol == symplot)
2015-04-01 12:43:50 +00:00
return new PlotStatement(identToken->GetText(), paramToken->GetText());
2017-02-27 22:23:06 +00:00
return new DrawStatement(identToken->GetText(), paramToken->GetText());
2015-04-01 12:43:50 +00:00
}