sencha-lang/Sencha-lang/Parser.cpp

409 lines
8.5 KiB
C++

#include "Parser.h"
Parser::Parser(ContextManager * context)
{
this->context_manager = context;
error_message = "***ERRORS DURING PARSING***\n";
position_in_stream = 0;
in_statement = false;
program = static_cast<ProgramNode *>(tree.root);
}
Parser::~Parser()
{
}
void Parser::erase_all()
{
error_message = "***ERRORS DURING PARSING***\n";
position_in_stream = 0;
in_statement = false;
this->token_stream = vector<Token>();
delete program;
program = new ProgramNode();
}
string Parser::show_tokens()
{
string tokens = "";
for (unsigned int i = 0; i < token_stream.size(); i++)
{
tokens += token_stream[i].value + " ";
}
return tokens;
}
void Parser::add_tokens(vector<Token> tokens)
{
for (unsigned int i = 0; i < tokens.size(); i++)
{
token_stream.push_back(tokens[i]);
}
}
void Parser::error(string s)
{
error_message += s ;
}
bool Parser::read_next()
{
if(position_in_stream < token_stream.size())
{
current_token = token_stream[position_in_stream];
tok_value = current_token.get_value();
position_in_stream++;
return true;
}
else
{
current_token = Token(t_invalid_token, "");
tok_value = current_token.get_value();
return false;
}
}
ProgramNode * Parser::interpret()
{
read_next();
while(tok_value!= "") program->add_statement(statement());
return program;
}
bool Parser::peek(string s) {return tok_value == s;}
bool Parser::peek_one_ahead(string s)
{
if(position_in_stream < token_stream.size() - 1)
{
if(s == token_stream[position_in_stream].value)
return true;
}
return false;
}
bool Parser::accept(string s)
{
if(peek(s))
{
read_next();
return true;
}
else return false;
}
bool Parser::expect(string s)
{
if(!accept(s))
{
string error_message = "Error: expected ";
error_message += s;
error_message += " but received: " + tok_value + "\n";
error(error_message);
return false;
}
else return true;
}
bool Parser::is_type()
{
if(tok_value == "def" || tok_value == "string" || tok_value == "num")
{
read_next();
return true;
}
else return false;
}
ASTStatement * Parser::statement()
{
if(accept("{"))
{
BasicStatement * stat = new BasicStatement();
while(!accept("}")) stat->children.push_back(statement());
return stat;
}
else if(is_type())
{
DeclarationStatement * declaration = new DeclarationStatement(context_manager);
std::string identifier = tok_value;
read_next();
declaration->add_name(identifier);
if(accept("="))
{
ASTExpression * ae = expr();
declaration->add_right_value(ae);
accept(";");
}
if(expect("("))
{
int argc = 0;
while(tok_value != ")")
{
argc++;
is_type();
declaration->add_argument(tok_value);
read_next();
if(peek(")")) break;
expect(",");
}
expect(")");
if(!accept(";")) declaration->add_body(statement());
}
return declaration;
}
else if(accept("array"))
{
DeclarationStatement * declaration = new DeclarationStatement(context_manager);
std::string identifier = tok_value;
read_next();
declaration->add_name(identifier);
expect("[");
declaration->add_array_size(expr());
expect("]");
accept(";");
return declaration;
}
else if(accept("if"))
{
IfNode * ifStatement = new IfNode();
ifStatement->add_condition(expr());
ifStatement->add_body(statement());
if(accept("else")) ifStatement->add_else_block(statement());
return ifStatement;
}
else if(accept("repeat"))
{
RepeatStatement * repeat = new RepeatStatement(expr(), statement());
return repeat;
}
else if(accept("import"))
{
auto name_expression = expr()->execute();
cout << name_expression.repr() << endl;
if(name_expression.type == SenchaObject::string_literal)
{
std::string name_of_import = name_expression.text;
ImportStatement * import = new ImportStatement(name_of_import, context_manager);
accept(";");
return import;
}
else if (name_expression.name != "")
{
std::string name_of_import = name_expression.name;
ImportStatement * import = new ImportStatement(name_of_import, context_manager);
accept(";");
return import;
}
else
{
string error_message = "ERROR: invalid import\n";
error(error_message);
BasicStatement * stat = new BasicStatement();
stat->add_expression(new IncorrectExpression(error_message));
accept(";");
return stat;
}
}
else if(accept("while"))
{
WhileNode * while_node = new WhileNode(expr(), statement());
return while_node;
}
else if(accept("return"))
{
BasicStatement * stat = new BasicStatement();
if(!peek(";")) stat->add_expression(expr());
expect(";");
return stat;
}
else
{
BasicStatement * stat = new BasicStatement();
stat->add_expression(expr());
while(!expect(";") && tok_value != "") read_next();
return stat;
}
}
ASTExpression * Parser::prim_expr()
{
if(current_token.get_type() == t_integer)
{
ConstantExpression * ce = new ConstantExpression(std::atoi(tok_value.c_str()));
read_next();
return ce;
}
else if(current_token.get_type() == t_float)
{
ConstantExpression * ce = new ConstantExpression(std::atof(tok_value.c_str()));
read_next();
return ce;
}
else if(current_token.get_type() == t_literal)
{
ConstantExpression * ce = new ConstantExpression(tok_value);
read_next();
return ce;
}
else if(current_token.get_type() == t_keyword)
{
ConstantExpression * ce;
if(tok_value == "true")
{
ce = new ConstantExpression( SenchaObject(true));
read_next();
}
else if (tok_value == "false")
{
ce = new ConstantExpression(SenchaObject(false));
read_next();
}
return ce;
}
else if(current_token.get_type() == t_symbol)
{
string name = current_token.value;
VariableExpression * ve = new VariableExpression(name, context_manager);
read_next();
return ve;
}
else if(accept("("))
{
ASTExpression * expression = expr();
expect(")");
return expression;
}
else
{
string error_message = "ERROR: unexpected primary expression " + tok_value + "\n";
error(error_message);
read_next();
return new IncorrectExpression(error_message);
}
}
ASTExpression * Parser::postfix_expr()
{
string name = tok_value;
if(current_token.get_type() == t_symbol)
{
if(peek_one_ahead("("))
{
read_next();
read_next();
PostfixExpression * function_call = new PostfixExpression(name, context_manager);
if(!accept(")"))
{
function_call->add_argument(expr());
while(accept(",")) function_call->add_argument(expr());
expect(")");
}
return function_call;
}
if(peek_one_ahead("["))
{
read_next();
read_next();
PostfixExpression * access = new PostfixExpression(name, context_manager, expr());
accept("]");
return access;
}
}
return prim_expr();
}
ASTExpression * Parser::unary_expr()
{
if(peek("-") || peek("!"))
{
string oper = tok_value;
read_next();
return new UnaryExpression(unary_expr(), oper);
}
else return postfix_expr();
}
ASTExpression * Parser::mul_expr()
{
ASTExpression * left = unary_expr();
if(peek("*") || peek("/"))
{
string oper = tok_value;
read_next();
return new BasicExpression(left, mul_expr(), oper);
}
else return left;
}
ASTExpression * Parser::add_expr()
{
ASTExpression * left = mul_expr();
if(peek("+") || peek("-"))
{
string oper = tok_value;
read_next();
return new BasicExpression(left, add_expr(), oper);
}
else return left;
}
ASTExpression * Parser::rel_expr()
{
ASTExpression * left = add_expr();
if(peek("<") || peek(">") || peek("<=") || peek(">="))
{
string oper = tok_value;
read_next();
return new BasicExpression(left, rel_expr(), oper);
}
else return left;
}
ASTExpression * Parser::eq_expr()
{
ASTExpression * left = rel_expr();
if(peek("==") || peek("!="))
{
string oper = tok_value;
read_next();
return new BasicExpression(left, eq_expr(), oper);
}
else return left;
}
ASTExpression * Parser::log_expr()
{
ASTExpression * left = eq_expr();
if(peek("and") || peek("or"))
{
string oper;
if(accept("and")) oper = "&&";
else if(accept("or")) oper = "||";
ASTExpression * right = log_expr();
return new BasicExpression(left, right, oper);
}
else return left;
}
ASTExpression * Parser::expr()
{
string name = tok_value;
ASTExpression * left = log_expr();
if(accept("="))
{
ASTExpression * right = expr();
std::string name_of_left_side = left->evaluate().name;
if(name_of_left_side != "")
name = name_of_left_side;
Assignment * assignment = new Assignment( context_manager, name, left, right);
return assignment;
}
else return left;
}