Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ FLEX_TARGET(MyScanner lexer.l ${CMAKE_BINARY_DIR}/lexer.cpp)
BISON_TARGET(MyParser parser.y ${CMAKE_BINARY_DIR}/parser.cpp)
ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)

set(HEADERS "shell.hpp" "lexer.h" "ast.hpp" "llvm.hpp")
set(HEADERS "shell.hpp" "lexer.h" "ast.hpp" "type_checker.hpp" "llvm.hpp")

set(SOURCES "main.cpp" "shell.cpp" "llvm.cpp")
set(SOURCES "main.cpp" "shell.cpp" "type_checker.cpp" "llvm.cpp")

add_executable(cplus ${HEADERS} ${SOURCES} ${BISON_MyParser_OUTPUTS} ${FLEX_MyScanner_OUTPUTS})

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Compiler for **C+** toy imperative language, based on [LLVM](https://llvm.org/do
2. Clone repo

```bash
git clone https://github.com/Sh3B0/cplus/
git clone https://github.com/Sh1co/cplus/
cd cplus
```

Expand Down
28 changes: 26 additions & 2 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ struct Expression;
struct UnaryExpression;
struct BinaryExpression;
struct Identifier;
struct EmptyType;
struct IntType;
struct RealType;
struct BoolType;
struct ArrayType;
struct RecordType;
struct FunctionType;
struct IntLiteral;
struct RealLiteral;
struct BoolLiteral;
Expand All @@ -40,11 +42,13 @@ struct RoutineCall;
class Visitor {
public:
virtual void visit(ast::Program *program) = 0;
virtual void visit(ast::EmptyType *it) = 0;
virtual void visit(ast::IntType *it) = 0;
virtual void visit(ast::RealType *it) = 0;
virtual void visit(ast::BoolType *it) = 0;
virtual void visit(ast::ArrayType *at) = 0;
virtual void visit(ast::RecordType *rt) = 0;
virtual void visit(ast::FunctionType *ft) = 0;
virtual void visit(ast::IntLiteral *il) = 0;
virtual void visit(ast::RealLiteral *rl) = 0;
virtual void visit(ast::BoolLiteral *bl) = 0;
Expand All @@ -69,7 +73,7 @@ namespace ast {
template <typename Node> using node_ptr = std::shared_ptr<Node>;

// Enumerations
enum class TypeEnum { INT, REAL, BOOL, ARRAY, RECORD };
enum class TypeEnum { EMPTY, INT, REAL, BOOL, ARRAY, RECORD, FUNCTION };
enum class OperatorEnum { PLUS, MINUS, MUL, DIV, MOD, AND, OR, NOT, XOR, EQ, NEQ, LT, GT, LEQ, GEQ };

// Base class for AST nodes
Expand Down Expand Up @@ -103,6 +107,13 @@ struct Statement : virtual Node {
};

// <Types>
struct EmptyType : Type {
EmptyType() {}
TypeEnum getType() { return TypeEnum::EMPTY; }

void accept(Visitor *v) override { v->visit(this); }
};

struct IntType : Type {
IntType() {}
TypeEnum getType() { return TypeEnum::INT; }
Expand Down Expand Up @@ -151,6 +162,19 @@ struct RecordType : Type {
void accept(Visitor *v) override { v->visit(this); }
};

struct FunctionType : Type {
node_ptr<Type> from, to;

FunctionType(node_ptr<Type> from, node_ptr<Type> to) {
this->from = from;
this->to = to;
}

TypeEnum getType() { return TypeEnum::FUNCTION; }

void accept(Visitor *v) override { v->visit(this); }
};

// </Types>
// <Expressions>
struct UnaryExpression : Expression {
Expand Down Expand Up @@ -397,4 +421,4 @@ struct RoutineCall : Statement, Expression {
// </Statements>
} // namespace ast

#endif // AST_H
#endif // AST_H
8 changes: 6 additions & 2 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ The following rules are used in sections presenting language syntax:
- **integer**: supports integer numbers (8 bytes signed integers)
- **real**: supports real values (4 bytes)
- **boolean**: can only be true or false (1 byte)
- **string**: supports raw text

### User types

Expand Down Expand Up @@ -83,10 +84,12 @@ The following rules are used in sections presenting language syntax:
var a : integer is 20;
var b : boolean is false;
var c : real is 1.5;
var d : integer; # will not be initialized unless global
var d : string is "Hello AC+";
var e : integer; # will not be initialized unless global
var x is 5; # x becomes integer automatically
var y is true; # y becomes boolean automatically
var z is 0.5; # z becomes real automatically
var w is "HI!"; # w becomes string automatically
```

### Type Declaration:
Expand Down Expand Up @@ -139,7 +142,7 @@ var x : integer; # This is also a comment
### Arithmetic:
**Operators:**

- **+**: Addition
- **+**: Addition (With strings the strings get concatinated together)
- **-**: Subtraction
- *****: Multiplication
- **/**: Division
Expand All @@ -149,6 +152,7 @@ var x : integer; # This is also a comment

```python
var x is 5 + 5; # 10
var y is "a" + "b"; #"ab"
```
### Relational:
**Operators:**
Expand Down
5 changes: 5 additions & 0 deletions lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ alphanum [a-zA-Z_0-9\.]
return cplus::Parser::make_NEQ();
}

"->" {
LDEBUG("ARROW")
return cplus::Parser::make_ARROW();
}

true {
LDEBUG("BOOL_VAL")
return cplus::Parser::make_BOOL_VAL(true);
Expand Down
12 changes: 12 additions & 0 deletions llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,10 @@ void IRGenerator::visit(ast::BinaryExpression *exp) {
BLOCK_E("BinaryExpression")
}

void IRGenerator::visit(ast::EmptyType *it) {

}

void IRGenerator::visit(ast::IntType *it) {
tmp_t = int_t;
}
Expand Down Expand Up @@ -499,6 +503,14 @@ void IRGenerator::visit(ast::RecordType *rt) {
BLOCK_E("RecordType")
}

void IRGenerator::visit(ast::FunctionType *ft) {
BLOCK_B("FucntionType")

GERROR("Function Types are not supported");

BLOCK_E("FunctionType")
}

void IRGenerator::visit(ast::IntLiteral *il) {
tmp_v = llvm::ConstantInt::get(context, llvm::APInt(64, il->value, true));
tmp_t = int_t;
Expand Down
4 changes: 3 additions & 1 deletion llvm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ class IRGenerator : public Visitor {
IRGenerator();
void generate();
void visit(ast::Program *program) override;
void visit(ast::EmptyType *it) override;
void visit(ast::IntType *it) override;
void visit(ast::RealType *rt) override;
void visit(ast::BoolType *bt) override;
void visit(ast::ArrayType *at) override;
void visit(ast::RecordType *rt) override;
void visit(ast::FunctionType *ft) override;
void visit(ast::IntLiteral *il) override;
void visit(ast::RealLiteral *rl) override;
void visit(ast::BoolLiteral *bl) override;
Expand Down Expand Up @@ -68,4 +70,4 @@ class IRGenerator : public Visitor {
llvm::Type *pop_t();
};

#endif // LLVM_H
#endif // LLVM_H
6 changes: 5 additions & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "lexer.h"
#include "parser.hpp"
#include "shell.hpp"
#include "type_checker.hpp"
#include "llvm.hpp"

#define RED "\033[31m"
Expand Down Expand Up @@ -33,6 +34,9 @@ int main(int argc, char **argv) {
if(shell.debug) {
std::cout << CYAN << "[AST]:" << RESET << std::endl;
}

ast::TypeChecker type_checker;
program->accept(&type_checker);

IRGenerator gen;
program->accept(&gen);
Expand All @@ -49,4 +53,4 @@ int main(int argc, char **argv) {
}

return 0;
}
}
14 changes: 12 additions & 2 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
%token COLON SEMICOLON COMMA DDOT BECOMES // : ; , . .. :=
%token PLUS MINUS MUL DIV MOD // + - * / %
%token AND OR XOR NOT // and or xor not
%token LT GT EQ LEQ GEQ NEQ // < > = <= >= /=
%token LT GT EQ LEQ GEQ NEQ ARROW // < > = <= >= /= ->
%token ARRAY RECORD ROUTINE RETURN END // array record routine return end
%token PRINT PRINTLN STRING // print println <string>
%token IF THEN ELSE WHILE FOR IN LOOP REVERSE // if then else while for in loop reverse
Expand All @@ -35,7 +35,7 @@
%type <ast::node_ptr<ast::RoutineDeclaration>> ROUTINE_DECLARATION
%type <ast::node_ptr<ast::Expression>> EXPRESSION
%type <std::vector<ast::node_ptr<ast::Expression>>> EXPRESSIONS NON_EMPTY_EXPRESSIONS
%type <ast::node_ptr<ast::Type>> TYPE PRIMITIVE_TYPE ARRAY_TYPE RECORD_TYPE
%type <ast::node_ptr<ast::Type>> TYPE PRIMITIVE_TYPE ARRAY_TYPE RECORD_TYPE FUNCTION_TYPE
%type <ast::node_ptr<ast::Body>> BODY
%type <ast::node_ptr<ast::Identifier>> MODIFIABLE_PRIMARY
%type <ast::node_ptr<ast::Statement>> STATEMENT
Expand All @@ -53,6 +53,7 @@
%left AND
%left EQ NEQ XOR
%left LT LEQ GT GEQ
%right ARROW
%left PLUS MINUS
%left MUL DIV MOD
%right NOT
Expand Down Expand Up @@ -158,6 +159,8 @@ TYPE :
PRIMITIVE_TYPE
| ARRAY_TYPE
| RECORD_TYPE
| FUNCTION_TYPE
| CB_L TYPE CB_R { $$ = $2; }
| ID {
PDEBUG("ALIASED_TYPE_ACCESS")
$$ = program->types[$1];
Expand Down Expand Up @@ -194,6 +197,13 @@ VARIABLE_DECLARATIONS :
}
;

FUNCTION_TYPE :
TYPE ARROW TYPE {
PDEBUG("FUNCTION_TYPE")
$$ = std::make_shared<ast::FunctionType>($1, $3);
}
;

ROUTINE_DECLARATION :
ROUTINE ID B_L PARAMETERS B_R IS BODY END {
PDEBUG("PROCEDURE_DECLARATION")
Expand Down
Loading