It's alive! (implemented base interpreter)
This commit is contained in:
parent
9500cf9773
commit
3e5ba29283
6
Makefile
6
Makefile
@ -22,7 +22,7 @@ OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(CPP_FILES))
|
|||||||
$(shell mkdir -p $(dir $(OBJ_FILES)))
|
$(shell mkdir -p $(dir $(OBJ_FILES)))
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
all: clean $(BUILD_DIR)/bob
|
all: build run
|
||||||
|
|
||||||
# Rule to create necessary directories
|
# Rule to create necessary directories
|
||||||
$(DIRS):
|
$(DIRS):
|
||||||
@ -37,8 +37,12 @@ $(BUILD_DIR)/bob: $(OBJ_FILES)
|
|||||||
$(CC) $(CFLAGS) $^ -o $@
|
$(CC) $(CFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
|
||||||
|
run:
|
||||||
./$(BUILD_DIR)/bob
|
./$(BUILD_DIR)/bob
|
||||||
|
|
||||||
|
build: clean $(BUILD_DIR)/bob
|
||||||
|
|
||||||
|
|
||||||
# Clean build directory
|
# Clean build directory
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR)/*
|
rm -rf $(BUILD_DIR)/*
|
||||||
|
|||||||
@ -6,14 +6,14 @@
|
|||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
|
||||||
class ASTPrinter : public Visitor
|
class ASTPrinter : Visitor
|
||||||
{
|
{
|
||||||
sptr(Object) visitBinaryExpr(BinaryExpr* expression) override;
|
sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expr) override;
|
||||||
sptr(Object) visitGroupingExpr(GroupingExpr* expression) override;
|
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) override;
|
||||||
sptr(Object) visitLiteralExpr(LiteralExpr* expression) override;
|
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) override;
|
||||||
sptr(Object) visitUnaryExpr(UnaryExpr* expression) override;
|
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) override;
|
||||||
public:
|
public:
|
||||||
sptr(Object) print(Expr* expr);
|
sptr(Object) print(sptr(Expr) expr);
|
||||||
private:
|
private:
|
||||||
sptr(Object) parenthesize(std::string name, std::vector<sptr(Expr)> exprs);
|
sptr(Object) parenthesize(std::string name, std::vector<sptr(Expr)> exprs);
|
||||||
|
|
||||||
|
|||||||
@ -15,10 +15,10 @@ struct UnaryExpr;
|
|||||||
|
|
||||||
struct Visitor
|
struct Visitor
|
||||||
{
|
{
|
||||||
virtual sptr(Object) visitBinaryExpr(BinaryExpr* expression) = 0;
|
virtual sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expr) = 0;
|
||||||
virtual sptr(Object) visitGroupingExpr(GroupingExpr* expression) = 0;
|
virtual sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expr) = 0;
|
||||||
virtual sptr(Object) visitLiteralExpr(LiteralExpr* expression) = 0;
|
virtual sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expr) = 0;
|
||||||
virtual sptr(Object) visitUnaryExpr(UnaryExpr* expression) = 0;
|
virtual sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ struct Expr{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct BinaryExpr : Expr
|
struct BinaryExpr : Expr, public std::enable_shared_from_this<BinaryExpr>
|
||||||
{
|
{
|
||||||
const std::shared_ptr<Expr> left;
|
const std::shared_ptr<Expr> left;
|
||||||
const Token oper;
|
const Token oper;
|
||||||
@ -38,11 +38,11 @@ struct BinaryExpr : Expr
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
sptr(Object) accept(Visitor* visitor) override{
|
sptr(Object) accept(Visitor* visitor) override{
|
||||||
return visitor->visitBinaryExpr(this);
|
return visitor->visitBinaryExpr(shared_from_this() );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GroupingExpr : Expr
|
struct GroupingExpr : Expr, public std::enable_shared_from_this<GroupingExpr>
|
||||||
{
|
{
|
||||||
const std::shared_ptr<Expr> expression;
|
const std::shared_ptr<Expr> expression;
|
||||||
|
|
||||||
@ -50,23 +50,24 @@ struct GroupingExpr : Expr
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
sptr(Object) accept(Visitor* visitor) override{
|
sptr(Object) accept(Visitor* visitor) override{
|
||||||
return visitor->visitGroupingExpr(this);
|
return visitor->visitGroupingExpr(shared_from_this());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LiteralExpr : Expr
|
struct LiteralExpr : Expr, public std::enable_shared_from_this<LiteralExpr>
|
||||||
{
|
{
|
||||||
const std::string value;
|
const std::string value;
|
||||||
const bool isNumber;
|
const bool isNumber;
|
||||||
LiteralExpr(std::string value, bool isNumber) : value(value), isNumber(isNumber)
|
const bool isNull;
|
||||||
|
LiteralExpr(std::string value, bool isNumber, bool isNull) : value(value), isNumber(isNumber), isNull(isNull)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
sptr(Object) accept(Visitor* visitor) override{
|
sptr(Object) accept(Visitor* visitor) override{
|
||||||
return visitor->visitLiteralExpr(this);
|
return visitor->visitLiteralExpr(shared_from_this());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnaryExpr : Expr
|
struct UnaryExpr : Expr, public std::enable_shared_from_this<UnaryExpr>
|
||||||
{
|
{
|
||||||
const Token oper;
|
const Token oper;
|
||||||
const std::shared_ptr<Expr> right;
|
const std::shared_ptr<Expr> right;
|
||||||
@ -75,7 +76,7 @@ struct UnaryExpr : Expr
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
sptr(Object) accept(Visitor* visitor) override{
|
sptr(Object) accept(Visitor* visitor) override{
|
||||||
return visitor->visitUnaryExpr(this);
|
return visitor->visitUnaryExpr(shared_from_this());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
23
headers/Interpreter.h
Normal file
23
headers/Interpreter.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Expression.h"
|
||||||
|
#include "helperFunctions/ShortHands.h"
|
||||||
|
#include "TypeWrapper.h"
|
||||||
|
|
||||||
|
class Interpreter : Visitor
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
sptr(Object) visitBinaryExpr(sptr(BinaryExpr) expression) override;
|
||||||
|
sptr(Object) visitGroupingExpr(sptr(GroupingExpr) expression) override;
|
||||||
|
sptr(Object) visitLiteralExpr(sptr(LiteralExpr) expression) override;
|
||||||
|
sptr(Object) visitUnaryExpr(sptr(UnaryExpr) expression) override;
|
||||||
|
|
||||||
|
void interpret(sptr(Expr) expr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
sptr(Object) evaluate(sptr(Expr) expr);
|
||||||
|
bool isTruthy(sptr(Object) object);
|
||||||
|
bool isEqual(sptr(Object) a, sptr(Object) b);
|
||||||
|
|
||||||
|
std::string stringify(sptr(Object) object);
|
||||||
|
};
|
||||||
@ -5,14 +5,25 @@ struct Object
|
|||||||
virtual ~Object(){};
|
virtual ~Object(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Number : public Object
|
struct Number : Object
|
||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
explicit Number(double value) : value(value) {}
|
explicit Number(double value) : value(value) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct String : public Object
|
struct String : Object
|
||||||
{
|
{
|
||||||
std::string value;
|
std::string value;
|
||||||
explicit String(std::string str) : value(str) {}
|
explicit String(std::string str) : value(str) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Boolean : Object
|
||||||
|
{
|
||||||
|
bool value;
|
||||||
|
explicit Boolean(bool value) : value(value) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct None : public Object
|
||||||
|
{
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -4,6 +4,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../headers/Lexer.h"
|
#include "../headers/Lexer.h"
|
||||||
|
#include "../headers/Interpreter.h"
|
||||||
|
|
||||||
#define VERSION "0.0.1"
|
#define VERSION "0.0.1"
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ class Bob
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Lexer lexer;
|
Lexer lexer;
|
||||||
|
Interpreter interpreter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void runFile(std::string path);
|
void runFile(std::string path);
|
||||||
|
|||||||
@ -4,22 +4,22 @@
|
|||||||
#include "../headers/ASTPrinter.h"
|
#include "../headers/ASTPrinter.h"
|
||||||
|
|
||||||
|
|
||||||
sptr(Object) ASTPrinter::visitBinaryExpr(BinaryExpr* expression){
|
sptr(Object) ASTPrinter::visitBinaryExpr(sptr(BinaryExpr) expression){
|
||||||
std::cout << expression->left << std::endl;
|
std::cout << expression->left << std::endl;
|
||||||
return parenthesize(expression->oper.lexeme, std::vector<sptr(Expr)>{expression->left, expression->right});
|
return parenthesize(expression->oper.lexeme, std::vector<sptr(Expr)>{expression->left, expression->right});
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr(Object) ASTPrinter::visitGroupingExpr(GroupingExpr* expression){
|
sptr(Object) ASTPrinter::visitGroupingExpr(sptr(GroupingExpr) expression){
|
||||||
return parenthesize("group", std::vector<sptr(Expr)>{expression->expression});
|
return parenthesize("group", std::vector<sptr(Expr)>{expression->expression});
|
||||||
}
|
}
|
||||||
sptr(Object) ASTPrinter::visitLiteralExpr(LiteralExpr* expression){
|
sptr(Object) ASTPrinter::visitLiteralExpr(sptr(LiteralExpr) expression){
|
||||||
return msptr(String)(expression->value);
|
return msptr(String)(expression->value);
|
||||||
}
|
}
|
||||||
sptr(Object) ASTPrinter::visitUnaryExpr(UnaryExpr* expression){
|
sptr(Object) ASTPrinter::visitUnaryExpr(sptr(UnaryExpr) expression){
|
||||||
return parenthesize(expression->oper.lexeme, std::vector<sptr(Expr)>{expression->right});
|
return parenthesize(expression->oper.lexeme, std::vector<sptr(Expr)>{expression->right});
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr(Object) ASTPrinter::print(Expr *expr) {
|
sptr(Object) ASTPrinter::print(sptr(Expr) expr) {
|
||||||
return expr->accept(this);
|
return expr->accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
206
source/Interpreter.cpp
Normal file
206
source/Interpreter.cpp
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
//
|
||||||
|
// Created by Bobby Lucero on 5/27/23.
|
||||||
|
//
|
||||||
|
#include <utility>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <limits>
|
||||||
|
#include "../headers/Interpreter.h"
|
||||||
|
|
||||||
|
|
||||||
|
sptr(Object) Interpreter::visitLiteralExpr(sptr(LiteralExpr) expr) {
|
||||||
|
if(expr->isNull) return msptr(None)();
|
||||||
|
if(expr->isNumber) return msptr(Number)(std::stod(expr->value));
|
||||||
|
return msptr(String)(expr->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr(Object) Interpreter::visitGroupingExpr(sptr(GroupingExpr) expression) {
|
||||||
|
|
||||||
|
return evaluate(expression->expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr(Object) Interpreter::visitUnaryExpr(sptr(UnaryExpr) expression)
|
||||||
|
{
|
||||||
|
sptr(Object) right = evaluate(expression->right);
|
||||||
|
|
||||||
|
if(expression->oper.type == MINUS)
|
||||||
|
{
|
||||||
|
if(std::dynamic_pointer_cast<Number>(right))
|
||||||
|
{
|
||||||
|
double value = std::dynamic_pointer_cast<Number>(right)->value;
|
||||||
|
return msptr(Number)(-value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Operand must be a number when using: " + expression->oper.lexeme);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expression->oper.type == BANG)
|
||||||
|
{
|
||||||
|
return msptr(Boolean)(!isTruthy(right));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr(Object) Interpreter::visitBinaryExpr(sptr(BinaryExpr) expression)
|
||||||
|
{
|
||||||
|
sptr(Object) left = evaluate(expression->left);
|
||||||
|
sptr(Object) right = evaluate(expression->right);
|
||||||
|
|
||||||
|
switch (expression->oper.type) {
|
||||||
|
case BANG_EQUAL:
|
||||||
|
return msptr(Boolean)(!isEqual(left, right));
|
||||||
|
case DOUBLE_EQUAL:
|
||||||
|
return msptr(Boolean)(isEqual(left, right));
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(std::dynamic_pointer_cast<Number>(left) && std::dynamic_pointer_cast<Number>(right))
|
||||||
|
{
|
||||||
|
double left_double = std::dynamic_pointer_cast<Number>(left)->value;
|
||||||
|
double right_double = std::dynamic_pointer_cast<Number>(right)->value;
|
||||||
|
switch (expression->oper.type) {
|
||||||
|
case GREATER:
|
||||||
|
return msptr(Boolean)(left_double > right_double);
|
||||||
|
case GREATER_EQUAL:
|
||||||
|
return msptr(Boolean)(left_double >= right_double);
|
||||||
|
case LESS:
|
||||||
|
return msptr(Boolean)(left_double < right_double);
|
||||||
|
case LESS_EQUAL:
|
||||||
|
return msptr(Boolean)(left_double <= right_double);
|
||||||
|
case MINUS:
|
||||||
|
return msptr(Number)(left_double - right_double);
|
||||||
|
case PLUS:
|
||||||
|
return msptr(Number)(left_double + right_double);
|
||||||
|
case SLASH:
|
||||||
|
return msptr(Number)(left_double / right_double);
|
||||||
|
case STAR:
|
||||||
|
return msptr(Number)(left_double * right_double);
|
||||||
|
default:
|
||||||
|
return msptr(None)(); //unreachable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(std::dynamic_pointer_cast<String>(left) && std::dynamic_pointer_cast<String>(right))
|
||||||
|
{
|
||||||
|
std::string left_string = std::dynamic_pointer_cast<String>(left)->value;
|
||||||
|
std::string right_string = std::dynamic_pointer_cast<String>(right)->value;
|
||||||
|
return msptr(String)(left_string + right_string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Operands must be of same type when using: " + expression->oper.lexeme);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr(Object) Interpreter::evaluate(sptr(Expr) expr) {
|
||||||
|
return expr->accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Interpreter::isTruthy(sptr(Object) object) {
|
||||||
|
|
||||||
|
if(auto boolean = std::dynamic_pointer_cast<Boolean>(object))
|
||||||
|
{
|
||||||
|
boolean->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(auto obj = std::dynamic_pointer_cast<None>(object))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Interpreter::isEqual(sptr(Object) a, sptr(Object) b) {
|
||||||
|
if(auto left = std::dynamic_pointer_cast<Number>(a))
|
||||||
|
{
|
||||||
|
if(auto right = std::dynamic_pointer_cast<Number>(b))
|
||||||
|
{
|
||||||
|
return left->value == right->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(auto left = std::dynamic_pointer_cast<Boolean>(a))
|
||||||
|
{
|
||||||
|
if(auto right = std::dynamic_pointer_cast<Boolean>(b))
|
||||||
|
{
|
||||||
|
return left->value == right->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(auto left = std::dynamic_pointer_cast<String>(a))
|
||||||
|
{
|
||||||
|
if(auto right = std::dynamic_pointer_cast<String>(b))
|
||||||
|
{
|
||||||
|
return left->value == right->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(auto left = std::dynamic_pointer_cast<None>(a))
|
||||||
|
{
|
||||||
|
if(auto right = std::dynamic_pointer_cast<None>(b))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Interpreter::interpret(std::shared_ptr<Expr> expr) {
|
||||||
|
|
||||||
|
sptr(Object) value = evaluate(std::move(expr));
|
||||||
|
std::cout << stringify(value) << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Interpreter::stringify(std::shared_ptr<Object> object) {
|
||||||
|
if(std::dynamic_pointer_cast<None>(object))
|
||||||
|
{
|
||||||
|
return "None";
|
||||||
|
}
|
||||||
|
else if(auto num = std::dynamic_pointer_cast<Number>(object))
|
||||||
|
{
|
||||||
|
double integral = num->value;
|
||||||
|
double fractional = std::modf(num->value, &integral);
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
if(std::abs(fractional) < std::numeric_limits<double>::epsilon())
|
||||||
|
{
|
||||||
|
ss << std::fixed << std::setprecision(0) << integral;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << std::fixed << std::setprecision(std::numeric_limits<double>::digits10) << num->value;\
|
||||||
|
std::string str = ss.str();
|
||||||
|
str.erase(str.find_last_not_of('0') + 1, std::string::npos);
|
||||||
|
if (str.back() == '.') {
|
||||||
|
str.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(auto string = std::dynamic_pointer_cast<String>(object))
|
||||||
|
{
|
||||||
|
return string->value;
|
||||||
|
}
|
||||||
|
else if(auto Bool = std::dynamic_pointer_cast<Boolean>(object))
|
||||||
|
{
|
||||||
|
return Bool->value == 1 ? "true" : "false";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ std::vector<Token> Lexer::Tokenize(std::string source){
|
|||||||
}
|
}
|
||||||
else if(t == '"')
|
else if(t == '"')
|
||||||
{
|
{
|
||||||
std::string str = std::string(1, src[0]);
|
std::string str;
|
||||||
advance();
|
advance();
|
||||||
while(!src.empty() && src[0] != '"')
|
while(!src.empty() && src[0] != '"')
|
||||||
{
|
{
|
||||||
@ -134,7 +134,7 @@ std::vector<Token> Lexer::Tokenize(std::string source){
|
|||||||
}
|
}
|
||||||
else if(src[0] == '"')
|
else if(src[0] == '"')
|
||||||
{
|
{
|
||||||
str += '"';
|
|
||||||
advance();
|
advance();
|
||||||
tokens.push_back(Token{STRING, str, line});
|
tokens.push_back(Token{STRING, str, line});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,6 @@ sptr(Expr) Parser::term()
|
|||||||
|
|
||||||
while(match({MINUS, PLUS}))
|
while(match({MINUS, PLUS}))
|
||||||
{
|
{
|
||||||
std::cout << "Found comparison" << std::endl;
|
|
||||||
Token op = previous();
|
Token op = previous();
|
||||||
sptr(Expr) right = factor();
|
sptr(Expr) right = factor();
|
||||||
expr = msptr(BinaryExpr)(expr, op, right);
|
expr = msptr(BinaryExpr)(expr, op, right);
|
||||||
@ -84,12 +83,12 @@ sptr(Expr) Parser::unary()
|
|||||||
|
|
||||||
sptr(Expr) Parser::primary()
|
sptr(Expr) Parser::primary()
|
||||||
{
|
{
|
||||||
if(match({FALSE})) return msptr(LiteralExpr)("true", false);
|
if(match({FALSE})) return msptr(LiteralExpr)("true", false, false);
|
||||||
if(match({TRUE})) return msptr(LiteralExpr)("true", false);
|
if(match({TRUE})) return msptr(LiteralExpr)("true", false, false);
|
||||||
if(match({NONE})) return msptr(LiteralExpr)("none", false);
|
if(match({NONE})) return msptr(LiteralExpr)("none", false, false);
|
||||||
|
|
||||||
if(match({NUMBER})) return msptr(LiteralExpr)(previous().lexeme, true);
|
if(match({NUMBER})) return msptr(LiteralExpr)(previous().lexeme, true, false);
|
||||||
if(match({STRING})) return msptr(LiteralExpr)(previous().lexeme, false);
|
if(match({STRING})) return msptr(LiteralExpr)(previous().lexeme, false, false);
|
||||||
|
|
||||||
if(match({OPEN_PAREN}))
|
if(match({OPEN_PAREN}))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -51,11 +51,7 @@ void Bob::run(string source)
|
|||||||
vector<Token> tokens = lexer.Tokenize(source);
|
vector<Token> tokens = lexer.Tokenize(source);
|
||||||
Parser p(tokens);
|
Parser p(tokens);
|
||||||
shared_ptr<Expr> expr = p.parse();
|
shared_ptr<Expr> expr = p.parse();
|
||||||
|
interpreter.interpret(expr);
|
||||||
|
|
||||||
ASTPrinter printer;
|
|
||||||
|
|
||||||
cout << dynamic_pointer_cast<String>(printer.print(expr.get()))->value << endl;
|
|
||||||
|
|
||||||
|
|
||||||
for(Token t : tokens){
|
for(Token t : tokens){
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user