Skip to content

Commit

Permalink
feat: ValidationVisitor has now types
Browse files Browse the repository at this point in the history
Part of #25

It set type of expressions (just literals for now) and check that last
expression is an int (return type of program)
  • Loading branch information
Gashmob committed Sep 8, 2024
1 parent e041def commit 11a1561
Show file tree
Hide file tree
Showing 21 changed files with 457 additions and 9 deletions.
82 changes: 82 additions & 0 deletions include/filc/grammar/Type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* 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_TYPE_H
#define FILC_TYPE_H

#include <string>
#include <memory>

namespace filc {
class AbstractType {
public:
[[nodiscard]] virtual auto getName() const noexcept -> std::string = 0;

[[nodiscard]] virtual auto getDisplayName() const noexcept -> std::string = 0;

protected:
AbstractType() = default;
};

class Type final: public AbstractType {
public:
explicit Type(std::string name);

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

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

private:
std::string _name;
};

class PointerType final: public AbstractType {
public:
explicit PointerType(std::shared_ptr<AbstractType> pointed_type);

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

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

private:
std::shared_ptr<AbstractType> _pointed_type;
};

class AliasType final: public AbstractType {
public:
AliasType(std::string name, std::shared_ptr<AbstractType> aliased_type);

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

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

private:
std::string _name;
std::shared_ptr<AbstractType> _aliased_type;
};
}

auto operator==(const std::shared_ptr<filc::AbstractType> &a, const std::shared_ptr<filc::AbstractType> &b) -> bool;
auto operator!=(const std::shared_ptr<filc::AbstractType> &a, const std::shared_ptr<filc::AbstractType> &b) -> bool;

#endif // FILC_TYPE_H
6 changes: 6 additions & 0 deletions include/filc/grammar/expression/Expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "filc/grammar/ast.h"
#include "filc/grammar/Visitor.h"
#include "filc/grammar/Position.h"
#include "filc/grammar/Type.h"
#include <string>

namespace filc {
Expand All @@ -38,11 +39,16 @@ class Expression: public Visitable {

[[nodiscard]] auto getPosition() const -> const Position&;

auto setType(const std::shared_ptr<AbstractType> &type) -> void;

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

protected:
Expression();

private:
Position _position;
std::shared_ptr<AbstractType> _type;
};
}

Expand Down
2 changes: 2 additions & 0 deletions include/filc/utils/Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

#define WARNING "WARNING"
#define WARNING_COLOR "\033[33m"
#define ERROR "ERROR"
#define ERROR_COLOR "\033[31m"

namespace filc {
class Message final {
Expand Down
47 changes: 47 additions & 0 deletions include/filc/validation/Environment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* 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_ENVIRONMENT_H
#define FILC_ENVIRONMENT_H

#include "filc/grammar/Type.h"
#include <map>
#include <string>

namespace filc {
class Environment {
public:
Environment();

[[nodiscard]] auto hasType(const std::string &name) const -> bool;

[[nodiscard]] auto getType(const std::string &name) const -> const std::shared_ptr<AbstractType> &;

auto addType(const std::shared_ptr<AbstractType> &type) -> void;

private:
std::map<std::string, std::shared_ptr<AbstractType>> _types;
};
}

#endif // FILC_ENVIRONMENT_H
4 changes: 4 additions & 0 deletions include/filc/validation/ValidationVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define FILC_VALIDATIONVISITOR_H

#include "filc/grammar/Visitor.h"
#include "filc/validation/Environment.h"
#include <memory>
#include <stack>
#include <map>
Expand Down Expand Up @@ -54,6 +55,8 @@ class ValidationContext final {
return std::any_cast<T>(_values.top().at(key));
}

auto clear() -> void;

private:
std::stack<std::map<std::string, std::any>> _values;
};
Expand Down Expand Up @@ -84,6 +87,7 @@ class ValidationVisitor final : public Visitor {

private:
std::unique_ptr<ValidationContext> _context;
std::unique_ptr<Environment> _environment;
std::ostream &_out;
};
}
Expand Down
54 changes: 54 additions & 0 deletions src/grammar/Type.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/Type.h"
#include <utility>

using namespace filc;

Type::Type(std::string name) : _name(std::move(name)) {}

std::string Type::getName() const noexcept { return _name; }

std::string Type::getDisplayName() const noexcept { return getName(); }

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

auto PointerType::getName() const noexcept -> std::string { return _pointed_type->getName() + "*"; }

auto PointerType::getDisplayName() const noexcept -> std::string { return _pointed_type->getDisplayName() + "*"; }

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

auto AliasType::getName() const noexcept -> std::string { return _aliased_type->getName(); }

auto AliasType::getDisplayName() const noexcept -> std::string { return _name; }

auto operator==(const std::shared_ptr<AbstractType> &a, const std::shared_ptr<AbstractType> &b) -> bool {
return a->getName() == b->getName();
}

auto operator!=(const std::shared_ptr<AbstractType> &a, const std::shared_ptr<AbstractType> &b) -> bool {
return !(a == b);
}
4 changes: 4 additions & 0 deletions src/grammar/expression/Expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ Expression::Expression() = default;
auto Expression::setPosition(const Position &position) -> void { _position = position; }

auto Expression::getPosition() const -> const Position & { return _position; }

auto Expression::setType(const std::shared_ptr<AbstractType> &type) -> void { _type = type; }

auto Expression::getType() const -> const std::shared_ptr<AbstractType> & { return _type; }
67 changes: 67 additions & 0 deletions src/validation/Environment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* 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/validation/Environment.h"
#include <stdexcept>

using namespace filc;

Environment::Environment() {
addType(std::make_shared<Type>("i8"));
addType(std::make_shared<Type>("i16"));
addType(std::make_shared<Type>("i32"));
addType(std::make_shared<Type>("i64"));
addType(std::make_shared<Type>("i128"));
addType(std::make_shared<AliasType>("int", getType("i32")));

addType(std::make_shared<Type>("u8"));
addType(std::make_shared<Type>("u16"));
addType(std::make_shared<Type>("u32"));
addType(std::make_shared<Type>("u64"));
addType(std::make_shared<Type>("u128"));
addType(std::make_shared<AliasType>("uint", getType("u32")));

addType(std::make_shared<Type>("f32"));
addType(std::make_shared<Type>("f64"));

addType(std::make_shared<Type>("bool"));

addType(std::make_shared<AliasType>("char", getType("u8")));
addType(std::make_shared<PointerType>(getType("char")));
}

auto Environment::hasType(const std::string &name) const -> bool { return _types.find(name) != _types.end(); }

auto Environment::getType(const std::string &name) const -> const std::shared_ptr<AbstractType> & {
if (!hasType(name)) {
throw std::logic_error("Environment doesn't have type " + name);
}
return _types.at(name);
}

auto Environment::addType(const std::shared_ptr<AbstractType> &type) -> void {
if (hasType(type->getDisplayName())) {
throw std::logic_error("Environment already have type " + type->getDisplayName() + " aka " + type->getName());
}
_types[type->getDisplayName()] = type;
}
2 changes: 2 additions & 0 deletions src/validation/ValidationContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ auto ValidationContext::set(const std::string &key, const std::any &value) -> vo
auto ValidationContext::has(const std::string &key) const -> bool {
return _values.top().find(key) != _values.top().end();
}

auto ValidationContext::clear() -> void { _values.top().clear(); }
Loading

0 comments on commit 11a1561

Please sign in to comment.