Added variable assignments
This commit is contained in:
parent
03bfae9eb4
commit
7e0cead697
@ -6,12 +6,16 @@
|
|||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
|
||||||
class ASTPrinter : Visitor
|
class ASTPrinter : ExprVisitor
|
||||||
{
|
{
|
||||||
sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expr) override;
|
sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expr) override;
|
||||||
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) override;
|
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) override;
|
||||||
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) override;
|
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) override;
|
||||||
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) override;
|
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) override;
|
||||||
|
sptr(Object) visitAssignExpr(sptr(AssignExpr) expr) override;
|
||||||
|
sptr(Object) visitVariableExpr(sptr(VarExpr) expr) override;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sptr(Object) print(sptr(Expr) expr);
|
sptr(Object) print(sptr(Expr) expr);
|
||||||
private:
|
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 "helperFunctions/ShortHands.h"
|
||||||
#include "TypeWrapper.h"
|
#include "TypeWrapper.h"
|
||||||
|
|
||||||
|
struct AssignExpr;
|
||||||
struct BinaryExpr;
|
struct BinaryExpr;
|
||||||
struct GroupingExpr;
|
struct GroupingExpr;
|
||||||
struct LiteralExpr;
|
struct LiteralExpr;
|
||||||
struct UnaryExpr;
|
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) visitBinaryExpr(sptr(BinaryExpr) expr) = 0;
|
||||||
virtual sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) = 0;
|
virtual sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) = 0;
|
||||||
virtual sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) = 0;
|
virtual sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) = 0;
|
||||||
virtual sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) = 0;
|
virtual sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) = 0;
|
||||||
|
virtual sptr(Object) visitVariableExpr(sptr(VarExpr) expr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Expr{
|
struct Expr{
|
||||||
virtual sptr(Object) accept(Visitor* visitor) = 0;
|
virtual sptr(Object) accept(ExprVisitor* visitor) = 0;
|
||||||
virtual ~Expr(){}
|
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>
|
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)
|
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() );
|
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;
|
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());
|
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)
|
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());
|
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)
|
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());
|
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
|
#pragma once
|
||||||
#include "Expression.h"
|
#include "Expression.h"
|
||||||
|
#include "Statement.h"
|
||||||
#include "helperFunctions/ShortHands.h"
|
#include "helperFunctions/ShortHands.h"
|
||||||
#include "TypeWrapper.h"
|
#include "TypeWrapper.h"
|
||||||
|
#include "Environment.h"
|
||||||
|
|
||||||
class Interpreter : Visitor
|
class Interpreter : ExprVisitor, StmtVisitor
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -11,10 +13,19 @@ public:
|
|||||||
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expression) override;
|
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expression) override;
|
||||||
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expression) override;
|
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expression) override;
|
||||||
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) 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:
|
private:
|
||||||
|
|
||||||
|
Environment environment;
|
||||||
|
|
||||||
sptr(Object) evaluate(sptr(Expr) expr);
|
sptr(Object) evaluate(sptr(Expr) expr);
|
||||||
bool isTruthy(sptr(Object) object);
|
bool isTruthy(sptr(Object) object);
|
||||||
bool isEqual(sptr(Object) a, sptr(Object) b);
|
bool isEqual(sptr(Object) a, sptr(Object) b);
|
||||||
@ -22,4 +33,6 @@ private:
|
|||||||
std::string stringify(sptr(Object) object);
|
std::string stringify(sptr(Object) object);
|
||||||
|
|
||||||
bool isWholeNumer(double num);
|
bool isWholeNumer(double num);
|
||||||
|
|
||||||
|
void execute(std::shared_ptr<Stmt> statement);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
enum TokenType{
|
enum TokenType{
|
||||||
OPEN_PAREN, CLOSE_PAREN, OPEN_BRACE, CLOSE_BRACE,
|
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,
|
BINARY_OP,
|
||||||
|
|
||||||
@ -15,16 +15,16 @@ enum TokenType{
|
|||||||
GREATER, GREATER_EQUAL,
|
GREATER, GREATER_EQUAL,
|
||||||
LESS, LESS_EQUAL,
|
LESS, LESS_EQUAL,
|
||||||
|
|
||||||
IDENTIFIER, STRING, NUMBER,
|
IDENTIFIER, STRING, NUMBER, BOOL,
|
||||||
|
|
||||||
AND, OR, TRUE, FALSE, IF, ELSE, FUNCTION, FOR,
|
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
|
END_OF_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::string enum_mapping[] = {"OPEN_PAREN", "CLOSE_PAREN", "OPEN_BRACE", "CLOSE_BRACE",
|
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",
|
"BINARY_OP",
|
||||||
|
|
||||||
@ -33,10 +33,10 @@ inline std::string enum_mapping[] = {"OPEN_PAREN", "CLOSE_PAREN", "OPEN_BRACE",
|
|||||||
"GREATER", "GREATER_EQUAL",
|
"GREATER", "GREATER_EQUAL",
|
||||||
"LESS", "LESS_EQUAL",
|
"LESS", "LESS_EQUAL",
|
||||||
|
|
||||||
"IDENTIFIER", "STRING", "NUMBER",
|
"IDENTIFIER", "STRING", "NUMBER", "BOOL",
|
||||||
|
|
||||||
"AND", "OR", "TRUE", "FALSE", "IF", "ELSE", "FUNCTION", "FOR",
|
"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"};
|
"END_OF_FILE"};
|
||||||
|
|
||||||
@ -55,7 +55,8 @@ const std::map<std::string, TokenType> KEYWORDS {
|
|||||||
{"super", SUPER},
|
{"super", SUPER},
|
||||||
{"this", THIS},
|
{"this", THIS},
|
||||||
{"none", NONE},
|
{"none", NONE},
|
||||||
{"return", RETURN}
|
{"return", RETURN},
|
||||||
|
{"print", PRINT}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Token
|
struct Token
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Lexer.h"
|
#include "Lexer.h"
|
||||||
#include "Expression.h"
|
#include "Expression.h"
|
||||||
|
#include "Statement.h"
|
||||||
#include "TypeWrapper.h"
|
#include "TypeWrapper.h"
|
||||||
#include "helperFunctions/ShortHands.h"
|
#include "helperFunctions/ShortHands.h"
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Parser(std::vector<Token> tokens) : tokens(std::move(tokens)){};
|
explicit Parser(std::vector<Token> tokens) : tokens(std::move(tokens)){};
|
||||||
sptr(Expr) parse();
|
std::vector<sptr(Stmt)> parse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sptr(Expr) expression();
|
sptr(Expr) expression();
|
||||||
@ -33,7 +34,17 @@ private:
|
|||||||
Token peek();
|
Token peek();
|
||||||
Token previous();
|
Token previous();
|
||||||
Token consume(TokenType type, std::string message);
|
Token consume(TokenType type, std::string message);
|
||||||
|
sptr(Stmt) statement();
|
||||||
|
|
||||||
void sync();
|
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
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
virtual ~Object(){};
|
virtual ~Object(){};
|
||||||
@ -15,6 +16,10 @@ struct String : Object
|
|||||||
{
|
{
|
||||||
std::string value;
|
std::string value;
|
||||||
explicit String(std::string str) : value(str) {}
|
explicit String(std::string str) : value(str) {}
|
||||||
|
~String(){
|
||||||
|
std::cout << value.size() << std::endl;
|
||||||
|
std::cout << "String being destroyed..." << std::endl;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Boolean : Object
|
struct Boolean : Object
|
||||||
|
|||||||
@ -1,3 +1 @@
|
|||||||
//10 + 10
|
10 10;
|
||||||
//0xFF + 0xFF
|
|
||||||
0xFF + 0xFF00 == 0xFFFF
|
|
||||||
@ -39,3 +39,11 @@ sptr(Object) ASTPrinter::parenthesize(std::string name, std::vector<sptr(Expr)>
|
|||||||
return msptr(String)(builder);
|
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 <cmath>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <cmath>
|
||||||
#include "../headers/Interpreter.h"
|
#include "../headers/Interpreter.h"
|
||||||
#include "../headers/helperFunctions/HelperFunctions.h"
|
#include "../headers/helperFunctions/HelperFunctions.h"
|
||||||
|
|
||||||
@ -94,9 +95,12 @@ sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) expression)
|
|||||||
case PLUS:
|
case PLUS:
|
||||||
return msptr(Number)(left_double + right_double);
|
return msptr(Number)(left_double + right_double);
|
||||||
case SLASH:
|
case SLASH:
|
||||||
|
if(right_double == 0) throw std::runtime_error("DivisionByZeroError: Cannot divide by 0");
|
||||||
return msptr(Number)(left_double / right_double);
|
return msptr(Number)(left_double / right_double);
|
||||||
case STAR:
|
case STAR:
|
||||||
return msptr(Number)(left_double * right_double);
|
return msptr(Number)(left_double * right_double);
|
||||||
|
case PERCENT:
|
||||||
|
return msptr(Number)(fmod(left_double, right_double));
|
||||||
default:
|
default:
|
||||||
return msptr(None)(); //unreachable
|
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;
|
double right_number = std::dynamic_pointer_cast<Number>(right)->value;
|
||||||
if(isWholeNumer(right_number))
|
if(isWholeNumer(right_number))
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::string s;
|
||||||
for (int i = 0; i < (int)right_number; ++i) {
|
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
|
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) {
|
sptr(Object) Interpreter::evaluate(sptr(Expr) expr) {
|
||||||
return expr->accept(this);
|
return expr->accept(this);
|
||||||
}
|
}
|
||||||
@ -202,17 +256,10 @@ bool Interpreter::isEqual(sptr(Object) a, sptr(Object) b) {
|
|||||||
throw std::runtime_error("Invalid isEqual compariosn");
|
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) {
|
std::string Interpreter::stringify(std::shared_ptr<Object> object) {
|
||||||
if(std::dynamic_pointer_cast<None>(object))
|
if(std::dynamic_pointer_cast<None>(object))
|
||||||
{
|
{
|
||||||
return "None";
|
return "none";
|
||||||
}
|
}
|
||||||
else if(auto num = std::dynamic_pointer_cast<Number>(object))
|
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});
|
tokens.push_back(Token{STAR, std::string(1, t), line});
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
else if(t == '%')
|
||||||
|
{
|
||||||
|
tokens.push_back(Token{PERCENT, std::string(1, t), line});
|
||||||
|
advance();
|
||||||
|
}
|
||||||
else if(t == '=')
|
else if(t == '=')
|
||||||
{
|
{
|
||||||
std::string token = std::string(1, t);
|
std::string token = std::string(1, t);
|
||||||
|
|||||||
@ -10,7 +10,32 @@
|
|||||||
|
|
||||||
sptr(Expr) Parser::expression()
|
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()
|
sptr(Expr) Parser::equality()
|
||||||
@ -59,7 +84,7 @@ sptr(Expr) Parser::factor()
|
|||||||
{
|
{
|
||||||
sptr(Expr) expr = unary();
|
sptr(Expr) expr = unary();
|
||||||
|
|
||||||
while(match({SLASH, STAR}))
|
while(match({SLASH, STAR, PERCENT}))
|
||||||
{
|
{
|
||||||
Token op = previous();
|
Token op = previous();
|
||||||
sptr(Expr) right = unary();
|
sptr(Expr) right = unary();
|
||||||
@ -85,11 +110,15 @@ sptr(Expr) Parser::primary()
|
|||||||
{
|
{
|
||||||
if(match({FALSE})) return msptr(LiteralExpr)("false", false, false);
|
if(match({FALSE})) return msptr(LiteralExpr)("false", false, false);
|
||||||
if(match({TRUE})) return msptr(LiteralExpr)("true", 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({NUMBER})) return msptr(LiteralExpr)(previous().lexeme, true, false);
|
||||||
if(match({STRING})) return msptr(LiteralExpr)(previous().lexeme, false, false);
|
if(match({STRING})) return msptr(LiteralExpr)(previous().lexeme, false, false);
|
||||||
|
|
||||||
|
if(match( {IDENTIFIER})) {
|
||||||
|
return msptr(VarExpr)(previous());
|
||||||
|
}
|
||||||
|
|
||||||
if(match({OPEN_PAREN}))
|
if(match({OPEN_PAREN}))
|
||||||
{
|
{
|
||||||
sptr(Expr) expr = expression();
|
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 {
|
try {
|
||||||
vector<Token> tokens = lexer.Tokenize(source);
|
vector<Token> tokens = lexer.Tokenize(source);
|
||||||
|
// for(Token t : tokens){
|
||||||
|
// cout << "{type: " << enum_mapping[t.type] << ", value: " << t.lexeme << "}" << endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
Parser p(tokens);
|
Parser p(tokens);
|
||||||
shared_ptr<Expr> expr = p.parse();
|
vector<sptr(Stmt)> statements = p.parse();
|
||||||
interpreter.interpret(expr);
|
interpreter.interpret(statements);
|
||||||
//cout << "=========================" << endl;
|
//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>
|
template <typename T>
|
||||||
struct BinaryExpr : Expr<T>, Visitor<T>
|
struct BinaryExpr : Expr<T>, ExprVisitor<T>
|
||||||
{
|
{
|
||||||
const Expr<T> left;
|
const Expr<T> left;
|
||||||
const Token oper;
|
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)
|
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);
|
return visitor.visitBinaryExpr(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct GroupingExpr : Expr<T>, Visitor<T>
|
struct GroupingExpr : Expr<T>, ExprVisitor<T>
|
||||||
{
|
{
|
||||||
const Expr<T> expression;
|
const Expr<T> expression;
|
||||||
|
|
||||||
GroupingExpr(Expr<T> expression) : expression(expression)
|
GroupingExpr(Expr<T> expression) : expression(expression)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
T accept(Visitor<T> visitor){
|
T accept(ExprVisitor<T> visitor){
|
||||||
return visitor.visitGroupingExpr(this);
|
return visitor.visitGroupingExpr(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct LiteralExpr : Expr<T>, Visitor<T>
|
struct LiteralExpr : Expr<T>, ExprVisitor<T>
|
||||||
{
|
{
|
||||||
const std::string value;
|
const std::string value;
|
||||||
|
|
||||||
LiteralExpr(std::string value) : value(value)
|
LiteralExpr(std::string value) : value(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
T accept(Visitor<T> visitor){
|
T accept(ExprVisitor<T> visitor){
|
||||||
return visitor.visitLiteralExpr(this);
|
return visitor.visitLiteralExpr(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct UnaryExpr : Expr<T>, Visitor<T>
|
struct UnaryExpr : Expr<T>, ExprVisitor<T>
|
||||||
{
|
{
|
||||||
const Token oper;
|
const Token oper;
|
||||||
const Expr<T> right;
|
const Expr<T> right;
|
||||||
@ -45,7 +45,7 @@ struct UnaryExpr : Expr<T>, Visitor<T>
|
|||||||
UnaryExpr(Token oper, Expr<T> right) : oper(oper), right(right)
|
UnaryExpr(Token oper, Expr<T> right) : oper(oper), right(right)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
T accept(Visitor<T> visitor){
|
T accept(ExprVisitor<T> visitor){
|
||||||
return visitor.visitUnaryExpr(this);
|
return visitor.visitUnaryExpr(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user