Skip to content

Commit

Permalink
feat: Introduce new keyword
Browse files Browse the repository at this point in the history
Part of #51

`new` is used to create a pointer to a scalar value
  • Loading branch information
Gashmob committed Dec 2, 2024
1 parent 7a2ba31 commit e8016d2
Show file tree
Hide file tree
Showing 20 changed files with 333 additions and 14 deletions.
2 changes: 2 additions & 0 deletions include/filc/grammar/DumpVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class DumpVisitor final: public Visitor<void> {

auto visitAssignation(Assignation *assignation) -> void override;

auto visitPointer(Pointer *pointer) -> void override;

private:
std::ostream &_out;
int _indent_level;
Expand Down
12 changes: 11 additions & 1 deletion include/filc/grammar/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ class AbstractType {

auto setLLVMType(llvm::Type *type) -> void;

[[nodiscard]] auto getLLVMType() const -> llvm::Type *;
[[nodiscard]] auto getLLVMType(llvm::LLVMContext *context) -> llvm::Type *;

protected:
AbstractType() = default;

virtual auto generateLLVMType(llvm::LLVMContext *context) -> void = 0;

private:
llvm::Type *_llvm_type = nullptr;
};
Expand All @@ -60,6 +62,8 @@ class Type final : public AbstractType {

[[nodiscard]] auto toDisplay() const noexcept -> std::string override;

auto generateLLVMType(llvm::LLVMContext *context) -> void override;

private:
std::string _name;
};
Expand All @@ -74,6 +78,10 @@ class PointerType final : public AbstractType {

[[nodiscard]] auto toDisplay() const noexcept -> std::string override;

[[nodiscard]] auto getPointedType() const noexcept -> std::shared_ptr<AbstractType>;

auto generateLLVMType(llvm::LLVMContext *context) -> void override;

private:
std::shared_ptr<AbstractType> _pointed_type;
};
Expand All @@ -88,6 +96,8 @@ class AliasType final : public AbstractType {

[[nodiscard]] auto toDisplay() const noexcept -> std::string override;

auto generateLLVMType(llvm::LLVMContext *context) -> void override;

private:
std::string _name;
std::shared_ptr<AbstractType> _aliased_type;
Expand Down
2 changes: 2 additions & 0 deletions include/filc/grammar/Visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ template<typename Return> class Visitor {

virtual auto visitAssignation(Assignation *assignation) -> Return = 0;

virtual auto visitPointer(Pointer *pointer) -> Return = 0;

protected:
Visitor() = default;
};
Expand Down
2 changes: 2 additions & 0 deletions include/filc/grammar/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class Identifier;
class BinaryCalcul;

class Assignation;

class Pointer;
}

#endif // FILC_AST_H
53 changes: 53 additions & 0 deletions include/filc/grammar/pointer/Pointer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* MIT License
*
* Copyright (c) 2024-Present Kevin Traini
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef FILC_POINTER_H
#define FILC_POINTER_H

#include "filc/grammar/expression/Expression.h"

#include <memory>
#include <string>

namespace filc {
class Pointer final : public Expression {
public:
Pointer(std::string type_name, const std::shared_ptr<Expression> &value);

[[nodiscard]] auto getTypeName() const -> std::string;

[[nodiscard]] auto getValue() const -> std::shared_ptr<Expression>;

[[nodiscard]] auto getPointedType() const -> std::shared_ptr<AbstractType>;

auto acceptVoidVisitor(Visitor<void> *visitor) -> void override;

auto acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * override;

private:
std::string _type_name;
std::shared_ptr<Expression> _value;
};
} // namespace filc

#endif // FILC_POINTER_H
2 changes: 2 additions & 0 deletions include/filc/llvm/IRGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class IRGenerator final: public Visitor<llvm::Value *> {

auto visitAssignation(Assignation *assignation) -> llvm::Value * override;

auto visitPointer(Pointer *pointer) -> llvm::Value * override;

private:
std::unique_ptr<llvm::LLVMContext> _llvm_context;
std::unique_ptr<llvm::Module> _module;
Expand Down
2 changes: 2 additions & 0 deletions include/filc/validation/ValidationVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class ValidationVisitor final : public Visitor<void> {

auto visitAssignation(Assignation *assignation) -> void override;

auto visitPointer(Pointer *pointer) -> void override;

private:
std::unique_ptr<ValidationContext> _context;
std::unique_ptr<Environment> _environment;
Expand Down
9 changes: 9 additions & 0 deletions src/grammar/DumpVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "filc/grammar/calcul/Calcul.h"
#include "filc/grammar/identifier/Identifier.h"
#include "filc/grammar/literal/Literal.h"
#include "filc/grammar/pointer/Pointer.h"
#include "filc/grammar/program/Program.h"
#include "filc/grammar/variable/Variable.h"

Expand Down Expand Up @@ -144,6 +145,14 @@ auto DumpVisitor::visitAssignation(Assignation *assignation) -> void {
_indent_level--;
}

auto DumpVisitor::visitPointer(Pointer *pointer) -> void {
printIdent();
_out << "[Pointer:" << pointer->getTypeName() << "]\n";
_indent_level++;
pointer->getValue()->acceptVoidVisitor(this);
_indent_level--;
}

auto DumpVisitor::printIdent() const -> void {
_out << std::string(_indent_level, '\t');
}
1 change: 1 addition & 0 deletions src/grammar/FilLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ VAR: 'var';
VAL: 'val';
TRUE: 'true';
FALSE: 'false';
NEW: 'new';

// Operators
EQ: '=';
Expand Down
19 changes: 15 additions & 4 deletions src/grammar/FilParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ options {
#include "filc/grammar/calcul/Calcul.h"
#include "filc/grammar/identifier/Identifier.h"
#include "filc/grammar/assignation/Assignation.h"
#include "filc/grammar/pointer/Pointer.h"
#include <memory>
#include <vector>
}
Expand Down Expand Up @@ -63,6 +64,9 @@ expression returns[std::shared_ptr<filc::Expression> tree]
| i=IDENTIFIER {
$tree = std::make_shared<filc::Identifier>($i.text);
}
| p=pointer {
$tree = $p.tree;
}

// === Binary calcul ===
| el3=expression op3=MOD er3=expression {
Expand Down Expand Up @@ -135,20 +139,22 @@ number returns[std::shared_ptr<filc::Expression> tree]
variable_declaration returns[std::shared_ptr<filc::VariableDeclaration> tree]
@init {
bool is_constant = true;
std::string type;
std::string type_name;
std::shared_ptr<filc::Expression> value = nullptr;
}
@after {
$tree = std::make_shared<filc::VariableDeclaration>(is_constant, $name.text, type, value);
$tree = std::make_shared<filc::VariableDeclaration>(is_constant, $name.text, type_name, value);
}
: (VAL | VAR {
is_constant = false;
}) name=IDENTIFIER (COLON type=IDENTIFIER {
type = $type.text;
}) name=IDENTIFIER (COLON type {
type_name = $type.text;
})? (EQ value=expression {
value = $value.tree;
})?;

type : IDENTIFIER STAR?;

assignation returns[std::shared_ptr<filc::Assignation> tree]
: i1=IDENTIFIER EQ e1=expression {
$tree = std::make_shared<filc::Assignation>($i1.text, $e1.tree);
Expand All @@ -158,3 +164,8 @@ assignation returns[std::shared_ptr<filc::Assignation> tree]
calcul->setPosition(filc::Position($op, $e2.stop));
$tree = std::make_shared<filc::Assignation>($i2.text, calcul);
};

pointer returns[std::shared_ptr<filc::Pointer> tree]
: NEW t=IDENTIFIER LPAREN e=expression RPAREN {
$tree = std::make_shared<filc::Pointer>($t.text, $e.tree);
};
23 changes: 22 additions & 1 deletion src/grammar/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
#include "filc/grammar/Type.h"

#include <llvm/IR/DerivedTypes.h>
#include <utility>

using namespace filc;
Expand All @@ -31,7 +32,11 @@ auto AbstractType::setLLVMType(llvm::Type *type) -> void {
_llvm_type = type;
}

auto AbstractType::getLLVMType() const -> llvm::Type * {
auto AbstractType::getLLVMType(llvm::LLVMContext *context) -> llvm::Type * {
if (_llvm_type == nullptr) {
generateLLVMType(context);
}

return _llvm_type;
}

Expand All @@ -49,6 +54,10 @@ auto Type::toDisplay() const noexcept -> std::string {
return getName();
}

auto Type::generateLLVMType(llvm::LLVMContext *context) -> void {
throw std::logic_error("Should not be called for scalar types");
}

PointerType::PointerType(std::shared_ptr<AbstractType> pointed_type): _pointed_type(std::move(pointed_type)) {}

auto PointerType::getName() const noexcept -> std::string {
Expand All @@ -66,6 +75,14 @@ auto PointerType::toDisplay() const noexcept -> std::string {
return getName();
}

auto PointerType::getPointedType() const noexcept -> std::shared_ptr<AbstractType> {
return _pointed_type;
}

auto PointerType::generateLLVMType(llvm::LLVMContext *context) -> void {
setLLVMType(llvm::PointerType::getUnqual(_pointed_type->getLLVMType(context)));
}

AliasType::AliasType(std::string name, std::shared_ptr<AbstractType> aliased_type)
: _name(std::move(name)), _aliased_type(std::move(aliased_type)) {}

Expand All @@ -81,6 +98,10 @@ auto AliasType::toDisplay() const noexcept -> std::string {
return getDisplayName() + " aka " + getName();
}

auto AliasType::generateLLVMType(llvm::LLVMContext *context) -> void {
throw std::logic_error("Should not be called for scalar alias types");
}

auto operator==(const std::shared_ptr<AbstractType> &a, const std::shared_ptr<AbstractType> &b) -> bool {
return a->getName() == b->getName();
}
Expand Down
54 changes: 54 additions & 0 deletions src/grammar/pointer/Pointer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* MIT License
*
* Copyright (c) 2024-Present Kevin Traini
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "filc/grammar/pointer/Pointer.h"

using namespace filc;

Pointer::Pointer(std::string type_name, const std::shared_ptr<Expression> &value)
: _type_name(std::move(type_name)), _value(value) {}

auto Pointer::getTypeName() const -> std::string {
return _type_name;
}

auto Pointer::getValue() const -> std::shared_ptr<Expression> {
return _value;
}

auto Pointer::getPointedType() const -> std::shared_ptr<AbstractType> {
const auto type = std::dynamic_pointer_cast<PointerType>(getType());
if (type == nullptr) {
return nullptr;
}

return type->getPointedType();
}

auto Pointer::acceptVoidVisitor(Visitor<void> *visitor) -> void {
visitor->visitPointer(this);
}

auto Pointer::acceptIRVisitor(Visitor<llvm::Value *> *visitor) -> llvm::Value * {
return visitor->visitPointer(this);
}
12 changes: 11 additions & 1 deletion src/llvm/IRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "filc/grammar/variable/Variable.h"
#include "filc/llvm/CalculBuilder.h"

#include <filc/grammar/pointer/Pointer.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Verifier.h>
#include <llvm/MC/MCTargetOptions.h>
Expand Down Expand Up @@ -151,7 +152,9 @@ auto IRGenerator::visitStringLiteral(StringLiteral *literal) -> llvm::Value * {

auto IRGenerator::visitVariableDeclaration(VariableDeclaration *variable) -> llvm::Value * {
const auto global = new llvm::GlobalVariable(
variable->getType()->getLLVMType(), variable->isConstant(), llvm::GlobalValue::InternalLinkage
variable->getType()->getLLVMType(_llvm_context.get()),
variable->isConstant(),
llvm::GlobalValue::InternalLinkage
);
global->setName(variable->getName());
_module->insertGlobalVariable(global);
Expand Down Expand Up @@ -181,3 +184,10 @@ auto IRGenerator::visitAssignation(Assignation *assignation) -> llvm::Value * {
_builder->CreateStore(value, variable);
return value;
}

auto IRGenerator::visitPointer(Pointer *pointer) -> llvm::Value * {
const auto alloca = _builder->CreateAlloca(pointer->getPointedType()->getLLVMType(_llvm_context.get()));
_builder->CreateStore(pointer->getValue()->acceptIRVisitor(this), alloca);

return _builder->CreateLoad(pointer->getType()->getLLVMType(_llvm_context.get()), alloca);
}
Loading

0 comments on commit e8016d2

Please sign in to comment.