Added variable assignments
This commit is contained in:
parent
03bfae9eb4
commit
7e0cead697
@ -6,12 +6,16 @@
|
||||
#include <initializer_list>
|
||||
|
||||
|
||||
class ASTPrinter : Visitor
|
||||
class ASTPrinter : ExprVisitor
|
||||
{
|
||||
sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expr) override;
|
||||
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) override;
|
||||
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) override;
|
||||
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) override;
|
||||
sptr(Object) visitAssignExpr(sptr(AssignExpr) expr) override;
|
||||
sptr(Object) visitVariableExpr(sptr(VarExpr) expr) override;
|
||||
|
||||
|
||||
public:
|
||||
sptr(Object) print(sptr(Expr) expr);
|
||||
private:
|
||||
|
||||
21
headers/Environment.h
Normal file
21
headers/Environment.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include "TypeWrapper.h"
|
||||
#include "helperFunctions/ShortHands.h"
|
||||
#include "Lexer.h"
|
||||
|
||||
class Environment
|
||||
{
|
||||
public:
|
||||
|
||||
void define(std::string name, sptr(Object) value);
|
||||
|
||||
void assign(Token name, sptr(Object) value);
|
||||
|
||||
std::shared_ptr<Object> get(Token name);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, sptr(Object)> variables;
|
||||
|
||||
};
|
||||
@ -8,25 +8,42 @@
|
||||
#include "helperFunctions/ShortHands.h"
|
||||
#include "TypeWrapper.h"
|
||||
|
||||
struct AssignExpr;
|
||||
struct BinaryExpr;
|
||||
struct GroupingExpr;
|
||||
struct LiteralExpr;
|
||||
struct UnaryExpr;
|
||||
struct VarExpr;
|
||||
|
||||
struct Visitor
|
||||
struct ExprVisitor
|
||||
{
|
||||
virtual sptr(Object) visitAssignExpr(sptr(AssignExpr) expr) = 0;
|
||||
virtual sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expr) = 0;
|
||||
virtual sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) = 0;
|
||||
virtual sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) = 0;
|
||||
virtual sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) = 0;
|
||||
virtual sptr(Object) visitVariableExpr(sptr(VarExpr) expr) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct Expr{
|
||||
virtual sptr(Object) accept(Visitor* visitor) = 0;
|
||||
virtual sptr(Object) accept(ExprVisitor* visitor) = 0;
|
||||
virtual ~Expr(){}
|
||||
};
|
||||
|
||||
struct AssignExpr : Expr, public std::enable_shared_from_this<AssignExpr>
|
||||
{
|
||||
const Token name;
|
||||
const sptr(Expr) value;
|
||||
AssignExpr(Token name, sptr(Expr) value) : name(name), value(value)
|
||||
{
|
||||
}
|
||||
|
||||
sptr(Object) accept(ExprVisitor* visitor) override
|
||||
{
|
||||
return visitor->visitAssignExpr(shared_from_this());
|
||||
}
|
||||
};
|
||||
|
||||
struct BinaryExpr : Expr, public std::enable_shared_from_this<BinaryExpr>
|
||||
{
|
||||
@ -37,7 +54,7 @@ struct BinaryExpr : Expr, public std::enable_shared_from_this<BinaryExpr>
|
||||
BinaryExpr(sptr(Expr) left, Token oper, sptr(Expr) right) : left(left), oper(oper), right(right)
|
||||
{
|
||||
}
|
||||
sptr(Object) accept(Visitor* visitor) override{
|
||||
sptr(Object) accept(ExprVisitor* visitor) override{
|
||||
return visitor->visitBinaryExpr(shared_from_this() );
|
||||
}
|
||||
};
|
||||
@ -46,10 +63,10 @@ struct GroupingExpr : Expr, public std::enable_shared_from_this<GroupingExpr>
|
||||
{
|
||||
const std::shared_ptr<Expr> expression;
|
||||
|
||||
GroupingExpr(sptr(Expr) expression) : expression(expression)
|
||||
explicit GroupingExpr(sptr(Expr) expression) : expression(expression)
|
||||
{
|
||||
}
|
||||
sptr(Object) accept(Visitor* visitor) override{
|
||||
sptr(Object) accept(ExprVisitor* visitor) override{
|
||||
return visitor->visitGroupingExpr(shared_from_this());
|
||||
}
|
||||
};
|
||||
@ -62,7 +79,7 @@ struct LiteralExpr : Expr, public std::enable_shared_from_this<LiteralExpr>
|
||||
LiteralExpr(std::string value, bool isNumber, bool isNull) : value(value), isNumber(isNumber), isNull(isNull)
|
||||
{
|
||||
}
|
||||
sptr(Object) accept(Visitor* visitor) override{
|
||||
sptr(Object) accept(ExprVisitor* visitor) override{
|
||||
return visitor->visitLiteralExpr(shared_from_this());
|
||||
}
|
||||
};
|
||||
@ -75,10 +92,20 @@ struct UnaryExpr : Expr, public std::enable_shared_from_this<UnaryExpr>
|
||||
UnaryExpr(Token oper, sptr(Expr) right) : oper(oper), right(right)
|
||||
{
|
||||
}
|
||||
sptr(Object) accept(Visitor* visitor) override{
|
||||
sptr(Object) accept(ExprVisitor* visitor) override{
|
||||
return visitor->visitUnaryExpr(shared_from_this());
|
||||
}
|
||||
};
|
||||
|
||||
struct VarExpr : Expr, public std::enable_shared_from_this<VarExpr>
|
||||
{
|
||||
const Token name;
|
||||
explicit VarExpr(Token name) : name(name){};
|
||||
sptr(Object) accept(ExprVisitor* visitor) override
|
||||
{
|
||||
return visitor->visitVariableExpr(shared_from_this());
|
||||
}
|
||||
};
|
||||
|
||||
////
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
#include "Expression.h"
|
||||
#include "Statement.h"
|
||||
#include "helperFunctions/ShortHands.h"
|
||||
#include "TypeWrapper.h"
|
||||
#include "Environment.h"
|
||||
|
||||
class Interpreter : Visitor
|
||||
class Interpreter : ExprVisitor, StmtVisitor
|
||||
{
|
||||
|
||||
public:
|
||||
@ -11,10 +13,19 @@ public:
|
||||
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expression) override;
|
||||
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expression) override;
|
||||
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expression) override;
|
||||
sptr(Object) visitVariableExpr(sptr(VarExpr) expression) override;
|
||||
sptr(Object) visitAssignExpr(sptr(AssignExpr) expression) override;
|
||||
|
||||
void interpret(sptr(Expr) expr);
|
||||
void visitExpressionStmt(sptr(ExpressionStmt) statement) override;
|
||||
void visitPrintStmt(sptr(PrintStmt) statement) override;
|
||||
void visitVarStmt(sptr(VarStmt) statement) override;
|
||||
|
||||
void interpret(std::vector<sptr(Stmt)> statements);
|
||||
|
||||
private:
|
||||
|
||||
Environment environment;
|
||||
|
||||
sptr(Object) evaluate(sptr(Expr) expr);
|
||||
bool isTruthy(sptr(Object) object);
|
||||
bool isEqual(sptr(Object) a, sptr(Object) b);
|
||||
@ -22,4 +33,6 @@ private:
|
||||
std::string stringify(sptr(Object) object);
|
||||
|
||||
bool isWholeNumer(double num);
|
||||
|
||||
void execute(std::shared_ptr<Stmt> statement);
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
enum TokenType{
|
||||
OPEN_PAREN, CLOSE_PAREN, OPEN_BRACE, CLOSE_BRACE,
|
||||
COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR,
|
||||
COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR, PERCENT,
|
||||
|
||||
BINARY_OP,
|
||||
|
||||
@ -15,16 +15,16 @@ enum TokenType{
|
||||
GREATER, GREATER_EQUAL,
|
||||
LESS, LESS_EQUAL,
|
||||
|
||||
IDENTIFIER, STRING, NUMBER,
|
||||
IDENTIFIER, STRING, NUMBER, BOOL,
|
||||
|
||||
AND, OR, TRUE, FALSE, IF, ELSE, FUNCTION, FOR,
|
||||
WHILE, VAR, CLASS, SUPER, THIS, NONE, RETURN,
|
||||
WHILE, VAR, CLASS, SUPER, THIS, NONE, RETURN, PRINT,
|
||||
|
||||
END_OF_FILE
|
||||
};
|
||||
|
||||
inline std::string enum_mapping[] = {"OPEN_PAREN", "CLOSE_PAREN", "OPEN_BRACE", "CLOSE_BRACE",
|
||||
"COMMA", "DOT", "MINUS", "PLUS", "SEMICOLON", "SLASH", "STAR",
|
||||
"COMMA", "DOT", "MINUS", "PLUS", "SEMICOLON", "SLASH", "STAR", "PERCENT",
|
||||
|
||||
"BINARY_OP",
|
||||
|
||||
@ -33,10 +33,10 @@ inline std::string enum_mapping[] = {"OPEN_PAREN", "CLOSE_PAREN", "OPEN_BRACE",
|
||||
"GREATER", "GREATER_EQUAL",
|
||||
"LESS", "LESS_EQUAL",
|
||||
|
||||
"IDENTIFIER", "STRING", "NUMBER",
|
||||
"IDENTIFIER", "STRING", "NUMBER", "BOOL",
|
||||
|
||||
"AND", "OR", "TRUE", "FALSE", "IF", "ELSE", "FUNCTION", "FOR",
|
||||
"WHILE", "VAR", "CLASS", "SUPER", "THIS", "NONE", "RETURN",
|
||||
"WHILE", "VAR", "CLASS", "SUPER", "THIS", "NONE", "RETURN", "PRINT",
|
||||
|
||||
"END_OF_FILE"};
|
||||
|
||||
@ -55,7 +55,8 @@ const std::map<std::string, TokenType> KEYWORDS {
|
||||
{"super", SUPER},
|
||||
{"this", THIS},
|
||||
{"none", NONE},
|
||||
{"return", RETURN}
|
||||
{"return", RETURN},
|
||||
{"print", PRINT}
|
||||
};
|
||||
|
||||
struct Token
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <vector>
|
||||
#include "Lexer.h"
|
||||
#include "Expression.h"
|
||||
#include "Statement.h"
|
||||
#include "TypeWrapper.h"
|
||||
#include "helperFunctions/ShortHands.h"
|
||||
|
||||
@ -14,7 +15,7 @@ private:
|
||||
|
||||
public:
|
||||
explicit Parser(std::vector<Token> tokens) : tokens(std::move(tokens)){};
|
||||
sptr(Expr) parse();
|
||||
std::vector<sptr(Stmt)> parse();
|
||||
|
||||
private:
|
||||
sptr(Expr) expression();
|
||||
@ -33,7 +34,17 @@ private:
|
||||
Token peek();
|
||||
Token previous();
|
||||
Token consume(TokenType type, std::string message);
|
||||
sptr(Stmt) statement();
|
||||
|
||||
void sync();
|
||||
|
||||
std::shared_ptr<Stmt> printStatement();
|
||||
|
||||
std::shared_ptr<Stmt> expressionStatement();
|
||||
|
||||
std::shared_ptr<Stmt> declaration();
|
||||
|
||||
std::shared_ptr<Stmt> varDeclaration();
|
||||
|
||||
std::shared_ptr<Expr> assignment();
|
||||
};
|
||||
64
headers/Statement.h
Normal file
64
headers/Statement.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "helperFunctions/ShortHands.h"
|
||||
#include "TypeWrapper.h"
|
||||
#include "Expression.h"
|
||||
|
||||
struct ExpressionStmt;
|
||||
struct PrintStmt;
|
||||
struct VarStmt;
|
||||
|
||||
struct StmtVisitor
|
||||
{
|
||||
virtual void visitExpressionStmt(sptr(ExpressionStmt) stmt) = 0;
|
||||
virtual void visitPrintStmt(sptr(PrintStmt) stmt) = 0;
|
||||
virtual void visitVarStmt(sptr(VarStmt) stmt) = 0;
|
||||
};
|
||||
|
||||
struct Stmt
|
||||
{
|
||||
const sptr(Expr) expression;
|
||||
virtual void accept(StmtVisitor* visitor) = 0;
|
||||
virtual ~Stmt(){};
|
||||
};
|
||||
|
||||
struct ExpressionStmt : Stmt, public std::enable_shared_from_this<ExpressionStmt>
|
||||
{
|
||||
const sptr(Expr) expression;
|
||||
explicit ExpressionStmt(sptr(Expr) expression) : expression(expression)
|
||||
{
|
||||
}
|
||||
|
||||
void accept(StmtVisitor* visitor) override
|
||||
{
|
||||
visitor->visitExpressionStmt(shared_from_this());
|
||||
}
|
||||
};
|
||||
|
||||
struct PrintStmt : Stmt, public std::enable_shared_from_this<PrintStmt>
|
||||
{
|
||||
const sptr(Expr) expression;
|
||||
explicit PrintStmt(sptr(Expr) expression) : expression(expression)
|
||||
{
|
||||
}
|
||||
|
||||
void accept(StmtVisitor* visitor) override
|
||||
{
|
||||
visitor->visitPrintStmt(shared_from_this());
|
||||
}
|
||||
};
|
||||
|
||||
struct VarStmt : Stmt, public std::enable_shared_from_this<VarStmt>
|
||||
{
|
||||
Token name;
|
||||
const sptr(Expr) initializer;
|
||||
VarStmt(Token name, sptr(Expr) initializer) : name(name), initializer(initializer)
|
||||
{
|
||||
}
|
||||
|
||||
void accept(StmtVisitor* visitor) override
|
||||
{
|
||||
visitor->visitVarStmt(shared_from_this());
|
||||
}
|
||||
};
|
||||
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
struct Object
|
||||
{
|
||||
virtual ~Object(){};
|
||||
@ -15,6 +16,10 @@ struct String : Object
|
||||
{
|
||||
std::string value;
|
||||
explicit String(std::string str) : value(str) {}
|
||||
~String(){
|
||||
std::cout << value.size() << std::endl;
|
||||
std::cout << "String being destroyed..." << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
struct Boolean : Object
|
||||
|
||||
@ -1,3 +1 @@
|
||||
//10 + 10
|
||||
//0xFF + 0xFF
|
||||
0xFF + 0xFF00 == 0xFFFF
|
||||
10 10;
|
||||
@ -39,3 +39,11 @@ sptr(Object) ASTPrinter::parenthesize(std::string name, std::vector<sptr(Expr)>
|
||||
return msptr(String)(builder);
|
||||
|
||||
}
|
||||
|
||||
sptr(Object) ASTPrinter::visitAssignExpr(std::shared_ptr<AssignExpr> expr) {
|
||||
return std::shared_ptr<String>();
|
||||
}
|
||||
|
||||
sptr(Object) ASTPrinter::visitVariableExpr(std::shared_ptr<VarExpr> expr) {
|
||||
return std::shared_ptr<String>();
|
||||
}
|
||||
|
||||
34
source/Environment.cpp
Normal file
34
source/Environment.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by Bobby Lucero on 5/30/23.
|
||||
//
|
||||
|
||||
#include "../headers/Environment.h"
|
||||
#include "../headers/Lexer.h"
|
||||
|
||||
|
||||
sptr(Object) Environment::get(Token name)
|
||||
{
|
||||
if(variables.count(name.lexeme))
|
||||
{
|
||||
return variables[name.lexeme];
|
||||
}
|
||||
|
||||
throw std::runtime_error("Undefined variable '" + name.lexeme + "'.");
|
||||
}
|
||||
|
||||
void Environment::define(std::string name, sptr(Object) value) {
|
||||
if(variables.count(name) > 0){
|
||||
throw std::runtime_error("'" + name + "' already defined.");
|
||||
}
|
||||
variables.insert(std::make_pair(name, value));
|
||||
}
|
||||
|
||||
void Environment::assign(Token name, std::shared_ptr<Object> value) {
|
||||
if(variables.count(name.lexeme) > 0)
|
||||
{
|
||||
variables[name.lexeme] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Undefined variable '" + name.lexeme + "'.");
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
#include "../headers/Interpreter.h"
|
||||
#include "../headers/helperFunctions/HelperFunctions.h"
|
||||
|
||||
@ -94,9 +95,12 @@ sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) expression)
|
||||
case PLUS:
|
||||
return msptr(Number)(left_double + right_double);
|
||||
case SLASH:
|
||||
if(right_double == 0) throw std::runtime_error("DivisionByZeroError: Cannot divide by 0");
|
||||
return msptr(Number)(left_double / right_double);
|
||||
case STAR:
|
||||
return msptr(Number)(left_double * right_double);
|
||||
case PERCENT:
|
||||
return msptr(Number)(fmod(left_double, right_double));
|
||||
default:
|
||||
return msptr(None)(); //unreachable
|
||||
}
|
||||
@ -120,11 +124,11 @@ sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) expression)
|
||||
double right_number = std::dynamic_pointer_cast<Number>(right)->value;
|
||||
if(isWholeNumer(right_number))
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::string s;
|
||||
for (int i = 0; i < (int)right_number; ++i) {
|
||||
ss << left_string;
|
||||
s += left_string;
|
||||
}
|
||||
return msptr(String)(ss.str());
|
||||
return msptr(String)(s);
|
||||
|
||||
}
|
||||
else
|
||||
@ -142,6 +146,56 @@ sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) expression)
|
||||
|
||||
}
|
||||
|
||||
sptr(Object) Interpreter::visitVariableExpr(sptr(VarExpr) expression)
|
||||
{
|
||||
return environment.get(expression->name);
|
||||
}
|
||||
|
||||
sptr(Object) Interpreter::visitAssignExpr(sptr(AssignExpr) expression) {
|
||||
sptr(Object) value = evaluate(expression->value);
|
||||
environment.assign(expression->name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void Interpreter::visitExpressionStmt(sptr(ExpressionStmt) statement) {
|
||||
evaluate(statement->expression);
|
||||
}
|
||||
|
||||
void Interpreter::visitPrintStmt(sptr(PrintStmt) statement) {
|
||||
sptr(Object) value = evaluate(statement->expression);
|
||||
std::cout << stringify(value) << std::endl;
|
||||
}
|
||||
|
||||
void Interpreter::visitVarStmt(sptr(VarStmt) statement)
|
||||
{
|
||||
sptr(Object) value = msptr(None)();
|
||||
if(!std::dynamic_pointer_cast<None>(statement->initializer))
|
||||
{
|
||||
value = evaluate(statement->initializer);
|
||||
}
|
||||
|
||||
//std::cout << "Visit var stmt: " << statement->name.lexeme << " set to: " << stringify(value) << std::endl;
|
||||
|
||||
environment.define(statement->name.lexeme, value);
|
||||
}
|
||||
|
||||
void Interpreter::interpret(std::vector<sptr(Stmt)> statements) {
|
||||
|
||||
|
||||
for(sptr(Stmt) s : statements)
|
||||
{
|
||||
execute(s);
|
||||
}
|
||||
|
||||
//std::cout << "\033[0;32m" << stringify(value) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void Interpreter::execute(sptr(Stmt) statement)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
|
||||
sptr(Object) Interpreter::evaluate(sptr(Expr) expr) {
|
||||
return expr->accept(this);
|
||||
}
|
||||
@ -202,17 +256,10 @@ bool Interpreter::isEqual(sptr(Object) a, sptr(Object) b) {
|
||||
throw std::runtime_error("Invalid isEqual compariosn");
|
||||
}
|
||||
|
||||
void Interpreter::interpret(std::shared_ptr<Expr> expr) {
|
||||
|
||||
sptr(Object) value = evaluate(std::move(expr));
|
||||
std::cout << "\033[0;32m" << stringify(value) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::string Interpreter::stringify(std::shared_ptr<Object> object) {
|
||||
if(std::dynamic_pointer_cast<None>(object))
|
||||
{
|
||||
return "None";
|
||||
return "none";
|
||||
}
|
||||
else if(auto num = std::dynamic_pointer_cast<Number>(object))
|
||||
{
|
||||
@ -267,3 +314,8 @@ bool Interpreter::isWholeNumer(double num) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -63,6 +63,11 @@ std::vector<Token> Lexer::Tokenize(std::string source){
|
||||
tokens.push_back(Token{STAR, std::string(1, t), line});
|
||||
advance();
|
||||
}
|
||||
else if(t == '%')
|
||||
{
|
||||
tokens.push_back(Token{PERCENT, std::string(1, t), line});
|
||||
advance();
|
||||
}
|
||||
else if(t == '=')
|
||||
{
|
||||
std::string token = std::string(1, t);
|
||||
|
||||
@ -10,7 +10,32 @@
|
||||
|
||||
sptr(Expr) Parser::expression()
|
||||
{
|
||||
return equality();
|
||||
return assignment();
|
||||
}
|
||||
|
||||
sptr(Expr) Parser::assignment()
|
||||
{
|
||||
|
||||
sptr(Expr) expr = equality();
|
||||
|
||||
if(match({EQUAL}))
|
||||
{
|
||||
Token equals = previous();
|
||||
|
||||
sptr(Expr) value = assignment();
|
||||
|
||||
if(std::dynamic_pointer_cast<VarExpr>(expr))
|
||||
{
|
||||
|
||||
Token name = std::dynamic_pointer_cast<VarExpr>(expr)->name;
|
||||
|
||||
return msptr(AssignExpr)(name, value);
|
||||
}
|
||||
|
||||
throw std::runtime_error("Invalid assignment target.");
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
sptr(Expr) Parser::equality()
|
||||
@ -59,7 +84,7 @@ sptr(Expr) Parser::factor()
|
||||
{
|
||||
sptr(Expr) expr = unary();
|
||||
|
||||
while(match({SLASH, STAR}))
|
||||
while(match({SLASH, STAR, PERCENT}))
|
||||
{
|
||||
Token op = previous();
|
||||
sptr(Expr) right = unary();
|
||||
@ -85,11 +110,15 @@ sptr(Expr) Parser::primary()
|
||||
{
|
||||
if(match({FALSE})) return msptr(LiteralExpr)("false", false, false);
|
||||
if(match({TRUE})) return msptr(LiteralExpr)("true", false, false);
|
||||
if(match({NONE})) return msptr(LiteralExpr)("none", false, false);
|
||||
if(match({NONE})) return msptr(LiteralExpr)("none", false, true);
|
||||
|
||||
if(match({NUMBER})) return msptr(LiteralExpr)(previous().lexeme, true, false);
|
||||
if(match({STRING})) return msptr(LiteralExpr)(previous().lexeme, false, false);
|
||||
|
||||
if(match( {IDENTIFIER})) {
|
||||
return msptr(VarExpr)(previous());
|
||||
}
|
||||
|
||||
if(match({OPEN_PAREN}))
|
||||
{
|
||||
sptr(Expr) expr = expression();
|
||||
@ -103,10 +132,62 @@ sptr(Expr) Parser::primary()
|
||||
///////////////////////////////////////////
|
||||
|
||||
|
||||
sptr(Expr) Parser::parse() {
|
||||
std::vector<sptr(Stmt)> Parser::parse() {
|
||||
|
||||
return expression();
|
||||
std::vector<sptr(Stmt)> statements;
|
||||
while(!isAtEnd())
|
||||
{
|
||||
statements.push_back(declaration());
|
||||
}
|
||||
|
||||
return statements;
|
||||
|
||||
}
|
||||
|
||||
sptr(Stmt) Parser::statement()
|
||||
{
|
||||
if(match({PRINT})) return printStatement();
|
||||
return expressionStatement();
|
||||
}
|
||||
|
||||
sptr(Stmt) Parser::printStatement()
|
||||
{
|
||||
sptr(Expr) value = expression();
|
||||
consume(SEMICOLON, "Expected ';' after value.");
|
||||
return msptr(PrintStmt)(value);
|
||||
}
|
||||
|
||||
sptr(Stmt) Parser::expressionStatement()
|
||||
{
|
||||
sptr(Expr) expr = expression();
|
||||
consume(SEMICOLON, "Expected ';' after expression.");
|
||||
return msptr(ExpressionStmt)(expr);
|
||||
}
|
||||
|
||||
sptr(Stmt) Parser::declaration()
|
||||
{
|
||||
try{
|
||||
if(match({VAR})) return varDeclaration();
|
||||
return statement();
|
||||
}
|
||||
catch(std::runtime_error e)
|
||||
{
|
||||
sync();
|
||||
throw std::runtime_error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
sptr(Stmt) Parser::varDeclaration()
|
||||
{
|
||||
Token name = consume(IDENTIFIER, "Expected variable name.");
|
||||
|
||||
sptr(Expr) initializer = msptr(LiteralExpr)("none", false, true);
|
||||
if(match({EQUAL}))
|
||||
{
|
||||
initializer = expression();
|
||||
}
|
||||
consume(SEMICOLON, "Expected ';' after variable declaration.");
|
||||
return msptr(VarStmt)(name, initializer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -49,17 +49,16 @@ void Bob::run(string source)
|
||||
{
|
||||
try {
|
||||
vector<Token> tokens = lexer.Tokenize(source);
|
||||
// for(Token t : tokens){
|
||||
// cout << "{type: " << enum_mapping[t.type] << ", value: " << t.lexeme << "}" << endl;
|
||||
// }
|
||||
|
||||
|
||||
Parser p(tokens);
|
||||
shared_ptr<Expr> expr = p.parse();
|
||||
interpreter.interpret(expr);
|
||||
vector<sptr(Stmt)> statements = p.parse();
|
||||
interpreter.interpret(statements);
|
||||
//cout << "=========================" << endl;
|
||||
ASTPrinter printer;
|
||||
|
||||
//cout << dynamic_pointer_cast<String>(printer.print(expr))->value << endl;
|
||||
|
||||
for(Token t : tokens){
|
||||
//cout << "{type: " << enum_mapping[t.type] << ", value: " << t.lexeme << "}" << endl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
16
testthing
16
testthing
@ -1,5 +1,5 @@
|
||||
template <typename T>
|
||||
struct BinaryExpr : Expr<T>, Visitor<T>
|
||||
struct BinaryExpr : Expr<T>, ExprVisitor<T>
|
||||
{
|
||||
const Expr<T> left;
|
||||
const Token oper;
|
||||
@ -8,36 +8,36 @@ struct BinaryExpr : Expr<T>, Visitor<T>
|
||||
BinaryExpr(Expr<T> left, Token oper, Expr<T> right) : left(left), oper(oper), right(right)
|
||||
{
|
||||
}
|
||||
T accept(Visitor<T> visitor){
|
||||
T accept(ExprVisitor<T> visitor){
|
||||
return visitor.visitBinaryExpr(this);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct GroupingExpr : Expr<T>, Visitor<T>
|
||||
struct GroupingExpr : Expr<T>, ExprVisitor<T>
|
||||
{
|
||||
const Expr<T> expression;
|
||||
|
||||
GroupingExpr(Expr<T> expression) : expression(expression)
|
||||
{
|
||||
}
|
||||
T accept(Visitor<T> visitor){
|
||||
T accept(ExprVisitor<T> visitor){
|
||||
return visitor.visitGroupingExpr(this);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct LiteralExpr : Expr<T>, Visitor<T>
|
||||
struct LiteralExpr : Expr<T>, ExprVisitor<T>
|
||||
{
|
||||
const std::string value;
|
||||
|
||||
LiteralExpr(std::string value) : value(value)
|
||||
{
|
||||
}
|
||||
T accept(Visitor<T> visitor){
|
||||
T accept(ExprVisitor<T> visitor){
|
||||
return visitor.visitLiteralExpr(this);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct UnaryExpr : Expr<T>, Visitor<T>
|
||||
struct UnaryExpr : Expr<T>, ExprVisitor<T>
|
||||
{
|
||||
const Token oper;
|
||||
const Expr<T> right;
|
||||
@ -45,7 +45,7 @@ struct UnaryExpr : Expr<T>, Visitor<T>
|
||||
UnaryExpr(Token oper, Expr<T> right) : oper(oper), right(right)
|
||||
{
|
||||
}
|
||||
T accept(Visitor<T> visitor){
|
||||
T accept(ExprVisitor<T> visitor){
|
||||
return visitor.visitUnaryExpr(this);
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user