Functions seem to work. Additionaly unary expressions :>.
parent
4526de47cf
commit
d65e408e55
|
@ -24,6 +24,7 @@
|
|||
#include "WhileNode.h"
|
||||
#include "RepeatStatement.h"
|
||||
#include "VariableExpression.h"
|
||||
#include "UnaryExpression.h"
|
||||
//And probably more
|
||||
//TODO actualize it
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* UnaryExpression.cpp
|
||||
*
|
||||
* Created on: Jan 1, 2013
|
||||
* Author: att
|
||||
*/
|
||||
|
||||
#include "UnaryExpression.h"
|
||||
|
||||
UnaryExpression::UnaryExpression(ASTNode * argument, std::string oper) {
|
||||
type = "UnaryExpression";
|
||||
children.push_back(argument);
|
||||
this->oper = oper;
|
||||
}
|
||||
|
||||
UnaryExpression::~UnaryExpression() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
SenchaObject UnaryExpression::execute()
|
||||
{
|
||||
auto argument = children[0];
|
||||
if(oper == "-") return - argument->execute();
|
||||
else if(oper == "!") return ! argument->execute();
|
||||
else return SenchaObject();
|
||||
}
|
||||
|
||||
SenchaObject UnaryExpression::evaluate()
|
||||
{
|
||||
return execute();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* UnaryExpression.h
|
||||
*
|
||||
* Created on: Jan 1, 2013
|
||||
* Author: att
|
||||
*/
|
||||
|
||||
#ifndef UNARYEXPRESSION_H_
|
||||
#define UNARYEXPRESSION_H_
|
||||
|
||||
#include "ASTExpression.h"
|
||||
|
||||
class UnaryExpression: public ASTExpression {
|
||||
public:
|
||||
|
||||
std::string oper;
|
||||
std::string get_operator() { return oper; }
|
||||
virtual void accept(Visitor * visitor) { visitor->visit(this); }
|
||||
|
||||
virtual SenchaObject execute();
|
||||
virtual SenchaObject evaluate();
|
||||
|
||||
UnaryExpression(ASTNode * argument, std::string oper);
|
||||
UnaryExpression();
|
||||
virtual ~UnaryExpression();
|
||||
};
|
||||
|
||||
#endif /* UNARYEXPRESSION_H_ */
|
|
@ -34,6 +34,10 @@ void ASTInspector::visit(Visitable * node)
|
|||
{
|
||||
visit(static_cast<BasicExpression *>(node));
|
||||
}
|
||||
else if (node->type == "UnaryExpression")
|
||||
{
|
||||
visit(static_cast<UnaryExpression *>(node));
|
||||
}
|
||||
else if (node->type == "PostfixExpression")
|
||||
{
|
||||
visit(static_cast<PostfixExpression *>(node));
|
||||
|
@ -118,6 +122,20 @@ void ASTInspector::visit(BasicExpression * basic_expression)
|
|||
depth_level--;
|
||||
}
|
||||
|
||||
void ASTInspector::visit(UnaryExpression * unary_expression)
|
||||
{
|
||||
this->occurences["UnaryExpression"]++;
|
||||
depth_level++;
|
||||
std::string visit_notes = "";
|
||||
visit_notes += "Unary expression:\n";
|
||||
visit_notes += "Executing " + unary_expression->get_operator() + " on:\n";
|
||||
write_report(visit_notes);
|
||||
unary_expression->children[0]->accept(this);
|
||||
|
||||
write_report("End of UnaryExpression\n");
|
||||
depth_level--;
|
||||
}
|
||||
|
||||
void ASTInspector::visit(PostfixExpression * postfix_expression)
|
||||
{
|
||||
this->occurences["PostfixExpression"]++;
|
||||
|
|
|
@ -34,6 +34,7 @@ private:
|
|||
void write_report(std::string visit_notes);
|
||||
void visit(ConstantExpression * node);
|
||||
void visit(BasicExpression * node);
|
||||
void visit(UnaryExpression * node);
|
||||
void visit(PostfixExpression * node);
|
||||
void visit(WhileNode * node);
|
||||
|
||||
|
|
|
@ -396,4 +396,19 @@ SenchaObject SenchaObject::operator<= (const SenchaObject& right) const
|
|||
return result;
|
||||
}
|
||||
|
||||
SenchaObject SenchaObject::operator-() const
|
||||
{
|
||||
SenchaObject result = *this;
|
||||
if(this->type == integer_number) result.integer = - result.integer;
|
||||
else if(this->type == float_number) result.number = - result.number;
|
||||
else result.type = invalid;
|
||||
return result;
|
||||
}
|
||||
SenchaObject SenchaObject::operator!() const
|
||||
{
|
||||
SenchaObject result = *this;
|
||||
if(this->type == boolean) result.truthy = ! result.truthy;
|
||||
else result.type = invalid;
|
||||
return result;
|
||||
}
|
||||
//TODO change code above to something more generic
|
||||
|
|
|
@ -61,7 +61,8 @@ public:
|
|||
virtual SenchaObject operator/(const SenchaObject& right)const;
|
||||
virtual SenchaObject operator==(const SenchaObject& right)const;
|
||||
virtual SenchaObject operator!=(const SenchaObject& right)const;
|
||||
|
||||
virtual SenchaObject operator-() const;
|
||||
virtual SenchaObject operator!() const;
|
||||
|
||||
|
||||
virtual ~SenchaObject();
|
||||
|
|
|
@ -107,21 +107,15 @@ pair<string, Token> Lexer::parse_token(string line)
|
|||
|
||||
for(i=0; i< line.size(); i++)
|
||||
{
|
||||
if(token_value == "" && isspace(line[i])) continue;
|
||||
if(token_value == "" && isspace(line[i])) continue;
|
||||
|
||||
if(isdigit(line[i]))
|
||||
if(isdigit(line[i]) || line[i] == '-')
|
||||
{
|
||||
token_value += line[i++];
|
||||
for(; i < line.size(); i++)
|
||||
{
|
||||
if(isdigit(line[i]) || line[i] == '.')
|
||||
{
|
||||
token_value += line[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(isdigit(line[i]) || line[i] == '.') token_value += line[i];
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,14 +131,8 @@ pair<string, Token> Lexer::parse_token(string line)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isalnum(line[i]) || line[i]== '_')
|
||||
{
|
||||
token_value += line[i];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if(isalnum(line[i]) || line[i]== '_') token_value += line[i];
|
||||
else if(ispunct(line[i]))
|
||||
{
|
||||
if(token_value=="")
|
||||
|
@ -161,17 +149,13 @@ pair<string, Token> Lexer::parse_token(string line)
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else break;
|
||||
}
|
||||
auto type = guess_type(token_value);
|
||||
if(type == t_literal) token_value = unescape_string(token_value);
|
||||
|
||||
if(type == t_literal) token_value = unescape_string(token_value);
|
||||
Token token = Token(type, token_value);
|
||||
string truncated_line = line.substr(i);
|
||||
|
||||
return pair<string, Token>(truncated_line, token);
|
||||
}
|
||||
|
||||
|
@ -209,14 +193,24 @@ type_of_token Lexer::guess_type(string value)
|
|||
typedef enum { t_invalid_token=0, t_symbol, t_integer, t_literal,
|
||||
t_punctuation, t_keyword } type_of_token;
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
if(value == "") return t_invalid_token;
|
||||
if(isdigit(value[0]))
|
||||
if(value == "") return t_invalid_token;
|
||||
if(value.size() == 1 )
|
||||
{
|
||||
if(is_punctuation(value[0])) return t_punctuation;
|
||||
else
|
||||
{
|
||||
if(is_operator(value)) return t_operator;
|
||||
}
|
||||
}
|
||||
if(value.size() == 2 && is_operator(value)) return t_operator;
|
||||
|
||||
if(isdigit(value[0]) || value[0] == '-')
|
||||
{
|
||||
bool is_number = true;
|
||||
bool dot_used = false;
|
||||
for(unsigned int i=0; i<value.size(); i++)
|
||||
for(unsigned int i=1; i<value.size(); i++)
|
||||
{
|
||||
if(value[i] == '.')
|
||||
{
|
||||
|
@ -242,25 +236,12 @@ type_of_token Lexer::guess_type(string value)
|
|||
{
|
||||
if(is_keyword(value)) return t_keyword;
|
||||
else return t_symbol;
|
||||
|
||||
}
|
||||
|
||||
if(value[0]=='\"')
|
||||
{
|
||||
if(value[value.size()-1] == '\"') return t_literal;
|
||||
else return t_invalid_token;
|
||||
}
|
||||
|
||||
if(value.size() == 1 )
|
||||
{
|
||||
if(is_punctuation(value[0])) return t_punctuation;
|
||||
else
|
||||
{
|
||||
if(is_operator(value)) return t_operator;
|
||||
}
|
||||
}
|
||||
if(value.size() == 2 && is_operator(value)) return t_operator;
|
||||
|
||||
//If any...
|
||||
return t_invalid_token;
|
||||
}
|
||||
|
|
|
@ -259,11 +259,7 @@ ASTExpression * Parser::postfix_expr()
|
|||
if(!accept(")"))
|
||||
{
|
||||
function_call->add_argument(expr());
|
||||
while(accept(","))
|
||||
{
|
||||
function_call->add_argument(expr());
|
||||
|
||||
}
|
||||
while(accept(",")) function_call->add_argument(expr());
|
||||
expect(")");
|
||||
}
|
||||
return function_call;
|
||||
|
@ -272,9 +268,20 @@ ASTExpression * Parser::postfix_expr()
|
|||
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 = postfix_expr();
|
||||
ASTExpression * left = unary_expr();
|
||||
if(peek("*") || peek("/"))
|
||||
{
|
||||
string oper = tok_value;
|
||||
|
|
|
@ -49,7 +49,8 @@ class Parser
|
|||
ASTExpression * log_expr();
|
||||
ASTExpression * mul_expr();
|
||||
ASTExpression * add_expr();
|
||||
ASTExpression * prim_expr();
|
||||
ASTExpression * prim_expr();
|
||||
ASTExpression * unary_expr();
|
||||
ASTExpression * postfix_expr();
|
||||
ASTExpression * rel_expr();
|
||||
ASTExpression * eq_expr();
|
||||
|
|
|
@ -199,7 +199,8 @@ void interactive()
|
|||
parser.interpret();
|
||||
parser.program->execute_last();
|
||||
inspector.visit(parser.program);
|
||||
//cout << inspector.get_report();
|
||||
//cout << parser.show_tokens();
|
||||
cout << inspector.get_report();
|
||||
inspector.forget_everything();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue