Functions seem to work. Additionaly unary expressions :>.

functions
Justyna Ilczuk 2013-01-01 18:05:35 +01:00
parent 4526de47cf
commit d65e408e55
11 changed files with 135 additions and 50 deletions

View File

@ -24,6 +24,7 @@
#include "WhileNode.h"
#include "RepeatStatement.h"
#include "VariableExpression.h"
#include "UnaryExpression.h"
//And probably more
//TODO actualize it

View File

@ -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();
}

View File

@ -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_ */

View File

@ -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"]++;

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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();

View File

@ -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();
}
}