Skip to content

Commit

Permalink
Type Check Pass (#36)
Browse files Browse the repository at this point in the history
* add most the pass

* finish typecheck

* code change

* update readme

* update readme
  • Loading branch information
jackparsonss committed Jun 27, 2024
1 parent 14cc99a commit 4c83ea2
Show file tree
Hide file tree
Showing 34 changed files with 462 additions and 137 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const y: i32 = x;

### Types
- **i32**: 32-bit integer
- **ch**: 8-bit character
- **ch**: 8-bit ascii character
- **bool**: 1-bit boolean(true/false)

### Functions
```
Expand Down Expand Up @@ -77,6 +78,12 @@ println(100);
- multiplication: `*`
- division: `/`
- modulus: `%`
- greater than(eq): `>`, `>=`
- less than(eq): `<`, `<=`
- equal: `==`
- not equal: `!=`
- and: `&&`
- or: `||`
```
fn main(): i32 {
let a: i32 = 5 + 5;
Expand All @@ -85,6 +92,15 @@ fn main(): i32 {
let m: i32 = 5 * 5;
let d: i32 = 5 / 5;
let r: i32 = 5 % 5;
let gt: bool = 5 > 4;
let lt: bool = 4 < 5;
let gte: bool = 5 >= 5;
let lte: bool = 5 >= 5;
let eq: bool = 5 == 5;
let ne: bool = 5 != 5;
let o: bool = 5 != 5 || 5 == 5;
let a: bool = 5 != 5 && 5 == 5;
}
```
```
Expand Down
15 changes: 15 additions & 0 deletions include/ast/passes/builtin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "ast/ast.h"
#include "ast/passes/pass.h"
#include "ast/symbol/symbol_table.h"

class Builtin : public Pass {
private:
shared_ptr<SymbolTable> symbol_table;
bool is_builtin(std::string name);

public:
explicit Builtin(shared_ptr<SymbolTable> symbol_table);
void visit_call(shared_ptr<ast::Call>) override;
};
7 changes: 2 additions & 5 deletions include/ast/passes/def_ref.h → include/ast/passes/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
#include "ast/symbol/symbol.h"
#include "ast/symbol/symbol_table.h"

class DefRef : public Pass {
class Define : public Pass {
private:
shared_ptr<SymbolTable> symbol_table;
bool is_builtin(std::string name);

public:
explicit DefRef(shared_ptr<SymbolTable> symbol_table);
void visit_variable(shared_ptr<ast::Variable>) override;
explicit Define(shared_ptr<SymbolTable> symbol_table);
void visit_declaration(shared_ptr<ast::Declaration>) override;
void visit_parameter(shared_ptr<ast::Parameter>) override;
void visit_function(shared_ptr<ast::Function>) override;
void visit_call(shared_ptr<ast::Call>) override;
};
6 changes: 2 additions & 4 deletions include/ast/passes/pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class Pass {
virtual void visit_return(shared_ptr<ast::Return>);
virtual void visit_binary_operator(shared_ptr<ast::BinaryOperator>);
virtual void visit_unary_operator(shared_ptr<ast::UnaryOperator>);
};

namespace pass {
void run_passes(shared_ptr<ast::Block> ast, shared_ptr<SymbolTable>);
}
static void run_passes(shared_ptr<ast::Block> ast, shared_ptr<SymbolTable>);
};
17 changes: 17 additions & 0 deletions include/ast/passes/reference.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "ast/ast.h"
#include "ast/passes/pass.h"
#include "ast/symbol/symbol.h"
#include "ast/symbol/symbol_table.h"

class Reference : public Pass {
private:
shared_ptr<SymbolTable> symbol_table;
bool is_builtin(std::string name);

public:
explicit Reference(shared_ptr<SymbolTable> symbol_table);
void visit_variable(shared_ptr<ast::Variable>) override;
void visit_call(shared_ptr<ast::Call>) override;
};
21 changes: 21 additions & 0 deletions include/ast/passes/type_check.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <stack>
#include "ast/ast.h"
#include "ast/passes/pass.h"

class TypeCheck : public Pass {
private:
std::stack<shared_ptr<ast::Function>> func_stack;
void check_numeric(Type type, size_t line);
void check_bool(Type type, size_t line);

public:
explicit TypeCheck();
void visit_declaration(shared_ptr<ast::Declaration>) override;
void visit_function(shared_ptr<ast::Function>) override;
void visit_call(shared_ptr<ast::Call>) override;
void visit_return(shared_ptr<ast::Return>) override;
void visit_binary_operator(shared_ptr<ast::BinaryOperator>) override;
void visit_unary_operator(shared_ptr<ast::UnaryOperator>) override;
};
30 changes: 30 additions & 0 deletions include/errors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once
#include <ostream>
#include <sstream>

class CompileTimeException : public std::exception {
protected:
std::string msg;

public:
const char* what() const noexcept override { return msg.c_str(); }
};

#define DEF_COMPILE_TIME_EXCEPTION(NAME) \
class NAME : public CompileTimeException { \
public: \
NAME(unsigned line, const std::string& description) { \
std::stringstream buf; \
buf << #NAME << " on Line " << line << ": " << description \
<< std::endl; \
msg = buf.str(); \
} \
}

DEF_COMPILE_TIME_EXCEPTION(MainError);

DEF_COMPILE_TIME_EXCEPTION(SymbolError);

DEF_COMPILE_TIME_EXCEPTION(SyntaxError);

DEF_COMPILE_TIME_EXCEPTION(TypeError);
1 change: 1 addition & 0 deletions include/shared/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extern shared_ptr<mlir::OpBuilder> builder;
extern mlir::MLIRContext context;

extern TypePtr ch;
extern TypePtr any;
extern TypePtr i32;
extern TypePtr f32;
extern TypePtr none;
Expand Down
1 change: 1 addition & 0 deletions include/shared/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Type {
bool operator==(const Type rhs) const;

static const Type ch;
static const Type any;
static const Type i32;
static const Type f32;
static const Type none;
Expand Down
5 changes: 4 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ set(
"${CMAKE_CURRENT_SOURCE_DIR}/ast/symbol/function_symbol.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/ast.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/passes/pass.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/passes/def_ref.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/passes/define.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/passes/reference.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/passes/type_check.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/passes/builtin.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/shared/type.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/shared/context.cpp"
)
Expand Down
6 changes: 1 addition & 5 deletions src/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,6 @@ void ast::Call::xml(int level) {
}

void ast::Call::set_function(shared_ptr<Function> func) {
if (this->function != nullptr) {
throw std::runtime_error("this call already has a function");
}

this->function = func;
this->set_type(func->get_type());
}
Expand All @@ -336,7 +332,7 @@ ast::BinaryOperator::BinaryOperator(BinaryOpType type,
shared_ptr<Expression> lhs,
shared_ptr<Expression> rhs,
Token* token)
: Expression(lhs->get_type(), token) {
: Expression(ctx::any, token) {
this->type = type;
this->lhs = lhs;
this->rhs = rhs;
Expand Down
3 changes: 0 additions & 3 deletions src/ast/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ std::any Builder::visitGtLtCond(FusionParser::GtLtCondContext* ctx) {
auto lhs = cast_node(ast::Expression, visit(ctx->expr()[0]));
auto rhs = cast_node(ast::Expression, visit(ctx->expr()[1]));
auto binop = make_shared<ast::BinaryOperator>(type, lhs, rhs, token);
binop->set_type(ctx::t_bool);

return to_node(binop);
}
Expand All @@ -309,7 +308,6 @@ std::any Builder::visitEqNeCond(FusionParser::EqNeCondContext* ctx) {
auto lhs = cast_node(ast::Expression, visit(ctx->expr()[0]));
auto rhs = cast_node(ast::Expression, visit(ctx->expr()[1]));
auto binop = make_shared<ast::BinaryOperator>(type, lhs, rhs, token);
binop->set_type(ctx::t_bool);

return to_node(binop);
}
Expand All @@ -330,7 +328,6 @@ std::any Builder::visitAndOrCond(FusionParser::AndOrCondContext* ctx) {
auto lhs = cast_node(ast::Expression, visit(ctx->expr()[0]));
auto rhs = cast_node(ast::Expression, visit(ctx->expr()[1]));
auto binop = make_shared<ast::BinaryOperator>(type, lhs, rhs, token);
binop->set_type(ctx::t_bool);

return to_node(binop);
}
Expand Down
35 changes: 35 additions & 0 deletions src/ast/passes/builtin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "ast/passes/builtin.h"
#include "ast/symbol/function_symbol.h"

Builtin::Builtin(shared_ptr<SymbolTable> symbol_table) : Pass("Builtin") {
this->symbol_table = symbol_table;
}

void Builtin::visit_call(shared_ptr<ast::Call> node) {
std::string name = node->get_name();
if (!is_builtin(name)) {
return;
}

name += "_" + node->arguments[0]->get_type()->get_name();
std::optional<SymbolPtr> var = symbol_table->resolve(name);
if (!var.has_value()) {
throw std::runtime_error("found undefined function: " + name);
}

shared_ptr<FunctionSymbol> vs =
dynamic_pointer_cast<FunctionSymbol>(var.value());
if (vs == nullptr) {
throw std::runtime_error("found non function in symbol table");
}

node->set_function(vs->function);
}

bool Builtin::is_builtin(std::string name) {
if (name == "print" || name == "println") {
return true;
}

return false;
}
97 changes: 0 additions & 97 deletions src/ast/passes/def_ref.cpp

This file was deleted.

Loading

0 comments on commit 4c83ea2

Please sign in to comment.