Permalink
Browse files

Got rid of assignment being an operator, that's not how turing works

  • Loading branch information...
1 parent ca2e5d9 commit f10169af85c18b8052f5dcdf9e03c31f76af0024 @trishume committed Apr 2, 2012
@@ -29,10 +29,6 @@ TURING_TKN(OP_REM,'rem' operator)
TURING_TKN(OP_SHL,'shl' operator)
TURING_TKN(OP_SHR,'shr' operator)
TURING_TKN(OP_XOR,'xor' operator)
-TURING_TKN(OP_ASSIGN_PLUS,+= operator)
-TURING_TKN(OP_ASSIGN_MINUS,-= operator)
-TURING_TKN(OP_ASSIGN_MULT,*= operator)
-TURING_TKN(OP_ASSIGN_DIVIDE,/= operator)
TURING_TKN(OP_ASSIGN,:= operator)
TURING_TKN(OP_EQ,= operator)
TURING_TKN(OP_IMPLIES,=> operator)
@@ -23,7 +23,7 @@ namespace OTParser {
public:
virtual ~InfixOp() {}
virtual ASTNode *parse(Parser *parser, ASTNode *left, Token token) = 0;
- virtual int getPrecedence() = 0;
+ virtual int getPrecedence(Parser *parser) = 0;
};
class UnaryOp : public PrefixOp {
public:
@@ -38,7 +38,7 @@ namespace OTParser {
//! \param isRight Is the operator right associative?
BinaryOp(ASTNode::Token type,int precedence, bool isRight);
virtual ASTNode *parse(Parser *parser, ASTNode *left, Token token);
- virtual int getPrecedence();
+ virtual int getPrecedence(Parser *parser);
private:
ASTNode::Token Type;
int Precedence;
@@ -10,8 +10,8 @@ namespace OTParser {
namespace Precedence {
//! Precedence levels from weakest to strongest binding
enum Levels {
- ASSIGN = 1,
- IMPLIES,
+ //ASSIGN, // Assignment is not an operator
+ IMPLIES = 1,
OR,
AND,
NOT,
@@ -56,8 +56,29 @@ namespace OTParser {
};
//! parses bracketed expressions (expr)
class GroupParselet : public PrefixOp {
+ public:
virtual ASTNode *parse(Parser *parser, Token token);
};
+ //! parses bracketed call expressions expr(expr[,expr]*)
+ class CallParselet : public InfixOp {
+ public:
+ virtual ASTNode *parse(Parser *parser, ASTNode *left,
+ Token token);
+ virtual int getPrecedence(Parser *parser);
+ };
+ //! parses binary operators that can use the short assign
+ //! syntax. I.E +/+= div/div= shl/shl=
+ /*class PossibleAssignBinOp : public InfixOp {
+ public:
+ PossibleAssignBinOp(int precedence) :
+ Prec(precedence) {}
+ virtual ASTNode *parse(Parser *parser, ASTNode *left,
+ Token token);
+ virtual int getPrecedence(Parser *parser);
+ private:
+ bool isAssign(Parser *parser) const;
+ int Prec;
+ };*/
}
}
View
@@ -186,18 +186,17 @@ namespace OTParser {
case '[': consume(); return newToken(Token::SQUARE_BRACKET_O, "[");
case ']': consume(); return newToken(Token::SQUARE_BRACKET_C, "]");
case '^': consume(); return newToken(Token::OP_DEREF, "^");
+
case '&': consume(); return newToken(Token::OP_AND, "&");
case '|': consume(); return newToken(Token::OP_OR, "|");
+ case '+': consume(); return newToken(Token::OP_PLUS,"+");
case '*':
consume();
switch (C) {
case '*':
consume();
return newToken(Token::OP_EXPONENT, "**");
- case '=':
- consume();
- return newToken(Token::OP_ASSIGN_MULT, "*=");
default:
return newToken(Token::OP_MULT, "*");
}
@@ -206,20 +205,12 @@ namespace OTParser {
return numLiteral();
}
consume(); // if it is not a number we can consume the -
- if (C=='=') {
- consume();
- return newToken(Token::OP_ASSIGN_MINUS, "-=");
- } else {
- return newToken(Token::OP_MINUS, "-");
- }
+ return newToken(Token::OP_MINUS, "-");
case '/':
consume();
switch (C) {
case '*':
skipBlockComment();
- case '=':
- consume();
- return newToken(Token::OP_ASSIGN_DIVIDE, "/=");
default:
return newToken(Token::OP_DIVIDE, "/");
}
@@ -236,7 +227,7 @@ namespace OTParser {
return newToken(Token::OP_DOT, ".");
// the macro expands in to a case statement for the first character
// which then checks for the second character.
- DIGRAPH('+', "+", Token::OP_PLUS, '=', "+=", Token::OP_ASSIGN_PLUS)
+
DIGRAPH(':', ":", Token::COLON, '=', ":=", Token::OP_ASSIGN)
DIGRAPH('=', "=", Token::OP_EQ, '=', "=>", Token::OP_IMPLIES)
DIGRAPH('<', "<", Token::OP_LT, '=', "<=", Token::OP_LE)
View
@@ -40,7 +40,7 @@ void testLexer(std::string fileName) {
int main(int argc, char** argv)
{
- SourceFile *f = new SourceFile("bob := (6*7 + 4 - 7 div 6**6.0 < 8 xor 5 and true or)");
+ SourceFile *f = new SourceFile("6*(7 + 4) - 7 div 6**6.0 < 8 xor 5 and true or false");
Lexer lex(f);
TuringParser parser(lex);
View
@@ -37,7 +37,7 @@ namespace OTParser {
return node;
}
- int BinaryOp::getPrecedence() {
+ int BinaryOp::getPrecedence(Parser *parser) {
return Precedence;
}
}
@@ -116,6 +116,6 @@ namespace OTParser {
if (InfixOps.find(type) == InfixOps.end()) {
return 0;
}
- return InfixOps[type]->getPrecedence();
+ return InfixOps[type]->getPrecedence(this);
}
}
View
@@ -24,12 +24,6 @@ namespace OTParser {
// register the infix parselets: Binary and postfix operators, calls
// -----------------------------------------------------------------
Parselet::InfixOp *op;
- op = new Parselet::BinaryOp(ASTNode::ASSIGN_OP, Precedence::ASSIGN,false);
- registerInfixOp(Token::OP_ASSIGN, op);
- registerInfixOp(Token::OP_ASSIGN_DIVIDE, op);
- registerInfixOp(Token::OP_ASSIGN_MINUS, op);
- registerInfixOp(Token::OP_ASSIGN_MULT, op);
- registerInfixOp(Token::OP_ASSIGN_PLUS, op);
op = new Parselet::BinaryOp(ASTNode::BIN_OP, Precedence::OR,false);
registerInfixOp(Token::OP_OR, op);
op = new Parselet::BinaryOp(ASTNode::BIN_OP, Precedence::AND,false);
@@ -58,6 +52,8 @@ namespace OTParser {
registerInfixOp(Token::OP_SHR, op);
op = new Parselet::BinaryOp(ASTNode::BIN_OP, Precedence::MODIFIER,false);
registerInfixOp(Token::OP_EXPONENT, op);
+ op = new Parselet::CallParselet();
+ registerInfixOp(Token::BRACKET_O, op);
}
TuringParser::~TuringParser() {
@@ -93,5 +89,39 @@ namespace OTParser {
parser->match(Token::BRACKET_C);
return node;
}
+ ASTNode *CallParselet::parse(Parser *parser, ASTNode *left, Token token) {
+ ASTNode *node = new ASTNode(ASTNode::CALL,token.Begin);
+ node->addChild(left); // TODO check for callable expression?
+ // we may have no arguments, so check for an immediate )
+ if (parser->curTok().Type != Token::BRACKET_C) {
+ do {
+ node->addChild(parser->parseExpression());
+ } while (parser->curTok().Type == Token::COMMA);
+ }
+ parser->match(Token::BRACKET_C);
+ return node;
+ }
+ int CallParselet::getPrecedence(Parser *parser) {
+ return Precedence::CALL;
+ }
+ /* Turing does not allow assignment as an expression but you can uncomment this and
+ use it if you want them.
+ ASTNode *PossibleAssignBinOp::parse(Parser *parser, ASTNode *left, Token token) {
+ bool assign = isAssign(parser);
+ if(assign) parser->consume(); // consume the =
+ ASTNode *node = new ASTNode(assign ? ASTNode::ASSIGN_OP : ASTNode::BIN_OP,token.Begin);
+ node->addChild(left); // TODO check for callable expression?
+
+ // Assignment has different precedence. It is also right associative so subtract one
+ int precedence = assign ? Precedence::ASSIGN - 1 : Prec;
+ node->addChild(parser->parseExpression(precedence)); // right side
+ return node;
+ }
+ int PossibleAssignBinOp::getPrecedence(Parser *parser) {
+ return isAssign(parser) ? Precedence::ASSIGN : Prec;
+ }
+ bool PossibleAssignBinOp::isAssign(Parser *parser) const {
+ return parser->lookahead(0).Type == Token::OP_EQ;
+ }*/
}
}

0 comments on commit f10169a

Please sign in to comment.