Rename libs/type -> libs/types, separate computed type tree from the AST type tree
This commit is contained in:
parent
437123f6f4
commit
4175a86ae3
31 changed files with 335 additions and 216 deletions
|
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.30)
|
||||
project(pslang CXX)
|
||||
|
||||
add_subdirectory(libs/type)
|
||||
add_subdirectory(libs/types)
|
||||
add_subdirectory(libs/ast)
|
||||
add_subdirectory(libs/parser)
|
||||
add_subdirectory(libs/jit)
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ file(GLOB_RECURSE PSLANG_AST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
|
|||
|
||||
add_library(pslang-ast STATIC ${PSLANG_AST_HEADERS} ${PSLANG_AST_SOURCES})
|
||||
target_include_directories(pslang-ast PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(pslang-ast PUBLIC pslang-type)
|
||||
target_link_libraries(pslang-ast PUBLIC pslang-types)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <pslang/ast/expression_fwd.hpp>
|
||||
#include <pslang/ast/location.hpp>
|
||||
#include <pslang/type/type.hpp>
|
||||
#include <pslang/ast/type.hpp>
|
||||
|
||||
namespace pslang::ast
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@ namespace pslang::ast
|
|||
struct cast_operation
|
||||
{
|
||||
expression_ptr expression;
|
||||
type::type_ptr type;
|
||||
type_ptr type;
|
||||
ast::location location;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include <pslang/ast/statement_fwd.hpp>
|
||||
#include <pslang/ast/expression_fwd.hpp>
|
||||
#include <pslang/ast/location.hpp>
|
||||
#include <pslang/type/type_fwd.hpp>
|
||||
#include <pslang/ast/type_fwd.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -16,13 +16,13 @@ namespace pslang::ast
|
|||
struct argument
|
||||
{
|
||||
std::string name;
|
||||
type::type_ptr type;
|
||||
type_ptr type;
|
||||
ast::location location;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<argument> arguments;
|
||||
type::type_ptr return_type;
|
||||
type_ptr return_type;
|
||||
statement_list_ptr statements;
|
||||
ast::location location;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <pslang/ast/function.hpp>
|
||||
#include <pslang/ast/struct.hpp>
|
||||
#include <pslang/ast/statement_fwd.hpp>
|
||||
#include <pslang/type/type.hpp>
|
||||
#include <pslang/ast/type.hpp>
|
||||
|
||||
#include <variant>
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ namespace pslang::ast
|
|||
{
|
||||
value_category category;
|
||||
std::string name;
|
||||
type::type_ptr type;
|
||||
type_ptr type;
|
||||
expression_ptr initializer;
|
||||
ast::location location;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/type/type_fwd.hpp>
|
||||
#include <pslang/ast/expression_fwd.hpp>
|
||||
#include <pslang/ast/type_fwd.hpp>
|
||||
#include <pslang/ast/location.hpp>
|
||||
|
||||
#include <string>
|
||||
|
|
@ -13,7 +13,7 @@ namespace pslang::ast
|
|||
struct field_definition
|
||||
{
|
||||
std::string name;
|
||||
type::type_ptr type;
|
||||
ast::type_ptr type;
|
||||
ast::location location;
|
||||
};
|
||||
|
||||
|
|
|
|||
49
libs/ast/include/pslang/ast/type.hpp
Normal file
49
libs/ast/include/pslang/ast/type.hpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/types/unit.hpp>
|
||||
#include <pslang/types/primitive.hpp>
|
||||
#include <pslang/types/array.hpp>
|
||||
#include <pslang/types/function.hpp>
|
||||
#include <pslang/types/type_fwd.hpp>
|
||||
#include <pslang/ast/location.hpp>
|
||||
#include <pslang/ast/type_fwd.hpp>
|
||||
|
||||
#include <variant>
|
||||
|
||||
namespace pslang::ast
|
||||
{
|
||||
|
||||
struct array_type
|
||||
{
|
||||
type_ptr element_type;
|
||||
std::uint64_t size;
|
||||
};
|
||||
|
||||
struct function_type
|
||||
{
|
||||
std::vector<type_ptr> arguments;
|
||||
type_ptr result;
|
||||
};
|
||||
|
||||
struct type_identifier
|
||||
{
|
||||
std::string name;
|
||||
ast::location location;
|
||||
std::size_t level = 0;
|
||||
};
|
||||
|
||||
using type_impl = std::variant<
|
||||
types::unit_type,
|
||||
types::primitive_type,
|
||||
array_type,
|
||||
function_type,
|
||||
type_identifier
|
||||
>;
|
||||
|
||||
struct type
|
||||
: type_impl
|
||||
{
|
||||
using type_impl::type_impl;
|
||||
};
|
||||
|
||||
}
|
||||
12
libs/ast/include/pslang/ast/type_fwd.hpp
Normal file
12
libs/ast/include/pslang/ast/type_fwd.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace pslang::ast
|
||||
{
|
||||
|
||||
struct type;
|
||||
|
||||
using type_ptr = std::shared_ptr<type>;
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include <pslang/ast/print.hpp>
|
||||
#include <pslang/type/print.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
#include <pslang/types/type.hpp>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
|
|
@ -21,6 +22,56 @@ namespace pslang::ast
|
|||
out << options.indent_string;
|
||||
}
|
||||
|
||||
void print(std::ostream & out, type const & type, print_options const & options);
|
||||
|
||||
void print_impl(std::ostream & out, types::unit_type const &, print_options const &)
|
||||
{
|
||||
out << "unit";
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, types::primitive_type const & type, print_options const &)
|
||||
{
|
||||
types::print(out, type);
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, array_type const & type, print_options const & options)
|
||||
{
|
||||
print(out, *type.element_type, options);
|
||||
out << "[" << type.size << "]";
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, function_type const & type, print_options const & options)
|
||||
{
|
||||
if (type.arguments.size() == 1)
|
||||
{
|
||||
print(out, *type.arguments.front(), options);
|
||||
out << " -> ";
|
||||
print(out, *type.result, options);
|
||||
return;
|
||||
}
|
||||
|
||||
out << '(';
|
||||
bool first = true;
|
||||
for (auto const & argument : type.arguments)
|
||||
{
|
||||
if (!first) out << ", ";
|
||||
first = false;
|
||||
print(out, *argument, options);
|
||||
}
|
||||
out << ") -> ";
|
||||
print(out, *type.result, options);
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, type_identifier const & type, print_options const & options)
|
||||
{
|
||||
out << type.name;
|
||||
}
|
||||
|
||||
void print(std::ostream & out, type const & type, print_options const & options)
|
||||
{
|
||||
std::visit([&](auto const & type){ print_impl(out, type, options); }, type);
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, bool_literal const & node, print_options const & options)
|
||||
{
|
||||
put_indent(out, options);
|
||||
|
|
@ -117,7 +168,7 @@ namespace pslang::ast
|
|||
{
|
||||
put_indent(out, options);
|
||||
out << "cast as ";
|
||||
type::print(out, *node.type);
|
||||
print(out, *node.type, options);
|
||||
out << '\n';
|
||||
print(out, node.expression, child(options));
|
||||
}
|
||||
|
|
@ -174,7 +225,7 @@ namespace pslang::ast
|
|||
if (node.type)
|
||||
{
|
||||
out << ", type = ";
|
||||
type::print(out, *node.type);
|
||||
print(out, *node.type, options);
|
||||
}
|
||||
out << " }\n";
|
||||
print(out, node.initializer, child(options));
|
||||
|
|
@ -234,13 +285,13 @@ namespace pslang::ast
|
|||
{
|
||||
put_indent(out, options);
|
||||
out << "function { name = \"" << node.name << "\", return type = ";
|
||||
type::print(out, *node.return_type);
|
||||
print(out, *node.return_type, options);
|
||||
out << " }\n";
|
||||
for (auto const & arg : node.arguments)
|
||||
{
|
||||
put_indent(out, child(options));
|
||||
out << "argument { name = \"" << arg.name << "\", type = ";
|
||||
type::print(out, *arg.type);
|
||||
print(out, *arg.type, options);
|
||||
out << " }\n";
|
||||
}
|
||||
put_indent(out, child(options));
|
||||
|
|
@ -260,7 +311,7 @@ namespace pslang::ast
|
|||
{
|
||||
put_indent(out, options);
|
||||
out << "field { name = \"" << node.name << "\", type = ";
|
||||
type::print(out, *node.type);
|
||||
print(out, *node.type, options);
|
||||
out << " }\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,29 +57,29 @@ namespace pslang::ast
|
|||
std::vector<scope> scopes;
|
||||
};
|
||||
|
||||
void resolve_identifiers(context & context, type::type & type);
|
||||
void resolve_identifiers(context & context, type & type);
|
||||
void resolve_identifiers(context & context, expression & expression);
|
||||
void resolve_identifiers(context & context, statement_list const & statements);
|
||||
|
||||
void resolve_identifiers_impl(context &, type::unit_type const &)
|
||||
void resolve_identifiers_impl(context &, types::unit_type const &)
|
||||
{}
|
||||
|
||||
void resolve_identifiers_impl(context &, type::primitive_type const &)
|
||||
void resolve_identifiers_impl(context &, types::primitive_type const &)
|
||||
{}
|
||||
|
||||
void resolve_identifiers_impl(context & context, type::array_type const & array_type)
|
||||
void resolve_identifiers_impl(context & context, array_type const & array_type)
|
||||
{
|
||||
resolve_identifiers(context, *array_type.element_type);
|
||||
}
|
||||
|
||||
void resolve_identifiers_impl(context & context, type::function_type const & function_type)
|
||||
void resolve_identifiers_impl(context & context, function_type const & function_type)
|
||||
{
|
||||
for (auto const & argument : function_type.arguments)
|
||||
resolve_identifiers(context, *argument);
|
||||
resolve_identifiers(context, *function_type.result);
|
||||
}
|
||||
|
||||
void resolve_identifiers_impl(context & context, type::identifier & identifier)
|
||||
void resolve_identifiers_impl(context & context, type_identifier & identifier)
|
||||
{
|
||||
for (auto it = context.scopes.rbegin(); it != context.scopes.rend(); ++it)
|
||||
{
|
||||
|
|
@ -94,7 +94,7 @@ namespace pslang::ast
|
|||
throw parse_error("Identifier \"" + identifier.name + "\" not found", {});
|
||||
}
|
||||
|
||||
void resolve_identifiers(context & context, type::type & type)
|
||||
void resolve_identifiers(context & context, type & type)
|
||||
{
|
||||
return std::visit([&](auto & type){ return resolve_identifiers_impl(context, type); }, type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,13 @@ namespace pslang::interpreter
|
|||
|
||||
struct struct_data
|
||||
{
|
||||
std::vector<ast::field_definition> fields;
|
||||
struct field
|
||||
{
|
||||
std::string name;
|
||||
types::type_ptr type;
|
||||
};
|
||||
|
||||
std::vector<field> fields;
|
||||
};
|
||||
|
||||
struct scope
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
#include <pslang/interpreter/context.hpp>
|
||||
#include <pslang/interpreter/value.hpp>
|
||||
#include <pslang/ast/expression_fwd.hpp>
|
||||
#include <pslang/ast/type_fwd.hpp>
|
||||
#include <pslang/types/type.hpp>
|
||||
|
||||
namespace pslang::interpreter
|
||||
{
|
||||
|
||||
type::type resolve_type(context & context, type::type const & type);
|
||||
types::type resolve_type(context & context, ast::type const & type);
|
||||
|
||||
value eval(context & context, ast::expression_ptr const & expression);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/type/type.hpp>
|
||||
#include <pslang/types/type.hpp>
|
||||
#include <pslang/ast/function.hpp>
|
||||
#include <pslang/interpreter/value_fwd.hpp>
|
||||
|
||||
|
|
@ -60,20 +60,26 @@ namespace pslang::interpreter
|
|||
struct array_value
|
||||
{
|
||||
// Can't infer type from elements in case of zero-sized array
|
||||
type::type_ptr element_type;
|
||||
types::type_ptr element_type;
|
||||
std::vector<value_ptr> elements;
|
||||
};
|
||||
|
||||
struct struct_value
|
||||
{
|
||||
type::type_ptr struct_type;
|
||||
types::type_ptr struct_type;
|
||||
std::unordered_map<std::string, value_ptr> fields;
|
||||
};
|
||||
|
||||
struct function_value
|
||||
{
|
||||
std::vector<ast::function_definition::argument> arguments;
|
||||
type::type_ptr return_type;
|
||||
struct argument
|
||||
{
|
||||
std::string name;
|
||||
types::type_ptr type;
|
||||
};
|
||||
|
||||
std::vector<argument> arguments;
|
||||
types::type_ptr return_type;
|
||||
ast::statement_list_ptr statements;
|
||||
};
|
||||
|
||||
|
|
@ -91,7 +97,7 @@ namespace pslang::interpreter
|
|||
using value_impl::value_impl;
|
||||
};
|
||||
|
||||
type::type type_of(value const & value);
|
||||
types::type type_of(value const & value);
|
||||
|
||||
void print(std::ostream & out, value const & value);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <pslang/interpreter/context.hpp>
|
||||
#include <pslang/type/print.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
|
||||
namespace pslang::interpreter
|
||||
{
|
||||
|
|
@ -20,7 +20,7 @@ namespace pslang::interpreter
|
|||
out << variable.first << " = ";
|
||||
print(out, variable.second.value);
|
||||
out << " (";
|
||||
type::print(out, type_of(variable.second.value));
|
||||
types::print(out, type_of(variable.second.value));
|
||||
out << ")\n";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <pslang/interpreter/exec.hpp>
|
||||
#include <pslang/interpreter/value.hpp>
|
||||
#include <pslang/ast/expression.hpp>
|
||||
#include <pslang/type/print.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
|
|
@ -13,44 +13,36 @@ namespace pslang::interpreter
|
|||
namespace
|
||||
{
|
||||
|
||||
type::type resolve_type_impl(context &, type::unit_type const & type)
|
||||
types::type resolve_type_impl(context &, types::unit_type const & type)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
type::type resolve_type_impl(context &, type::primitive_type const & type)
|
||||
types::type resolve_type_impl(context &, types::primitive_type const & type)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
type::type resolve_type_impl(context & context, type::array_type const & type)
|
||||
types::type resolve_type_impl(context & context, ast::array_type const & type)
|
||||
{
|
||||
return type::array_type{std::make_unique<type::type>(resolve_type(context, *type.element_type)), type.size};
|
||||
return types::array_type{std::make_unique<types::type>(resolve_type(context, *type.element_type)), type.size};
|
||||
}
|
||||
|
||||
type::type resolve_type_impl(context & context, type::function_type const & type)
|
||||
types::type resolve_type_impl(context & context, ast::function_type const & type)
|
||||
{
|
||||
type::function_type result;
|
||||
types::function_type result;
|
||||
for (auto const & argument : type.arguments)
|
||||
result.arguments.push_back(std::make_unique<type::type>(resolve_type(context, *argument)));
|
||||
result.result = std::make_unique<type::type>(resolve_type(context, *type.result));
|
||||
result.arguments.push_back(std::make_unique<types::type>(resolve_type(context, *argument)));
|
||||
result.result = std::make_unique<types::type>(resolve_type(context, *type.result));
|
||||
return result;
|
||||
}
|
||||
|
||||
type::type resolve_type_impl(context & context, type::identifier const & type)
|
||||
types::type resolve_type_impl(context & context, ast::type_identifier const & type)
|
||||
{
|
||||
for (auto it = context.scope_stack.rbegin(); it != context.scope_stack.rend(); ++it)
|
||||
{
|
||||
if (it->structs.count(type.name))
|
||||
{
|
||||
return type::identifier{std::string(it.base() - context.scope_stack.begin() - 1, '/') + type.name};
|
||||
}
|
||||
return types::named_type{type.name, type.level};
|
||||
}
|
||||
|
||||
throw std::runtime_error("Type \"" + type.name + "\" is not defined");
|
||||
}
|
||||
|
||||
type::type resolve_type_impl(context & context, type::type const & type)
|
||||
types::type resolve_type_impl(context & context, ast::type const & type)
|
||||
{
|
||||
return std::visit([&](auto const & type){ return resolve_type_impl(context, type); }, type);
|
||||
}
|
||||
|
|
@ -166,7 +158,7 @@ namespace pslang::interpreter
|
|||
{
|
||||
std::ostringstream os;
|
||||
os << "Cannot index into an array with an expression of type ";
|
||||
type::print(os, type_of(index));
|
||||
types::print(os, type_of(index));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +215,7 @@ namespace pslang::interpreter
|
|||
os << "Cannot apply unary operator \"";
|
||||
print(os, type);
|
||||
os << "\" to a value of type ";
|
||||
type::print(os, type_of(value));
|
||||
types::print(os, type_of(value));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +246,7 @@ namespace pslang::interpreter
|
|||
os << "Cannot apply unary operator \"";
|
||||
print(os, type);
|
||||
os << "\" to a value of type ";
|
||||
type::print(os, type_of(primitive_value(arg1)));
|
||||
types::print(os, type_of(primitive_value(arg1)));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -370,9 +362,9 @@ namespace pslang::interpreter
|
|||
os << "Cannot apply binary operator \"";
|
||||
print(os, type);
|
||||
os << "\" to values of type ";
|
||||
type::print(os, type_of(primitive_value(arg1)));
|
||||
types::print(os, type_of(primitive_value(arg1)));
|
||||
os << " and ";
|
||||
type::print(os, type_of(primitive_value(arg2)));
|
||||
types::print(os, type_of(primitive_value(arg2)));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -383,9 +375,9 @@ namespace pslang::interpreter
|
|||
os << "Cannot apply binary operator \"";
|
||||
print(os, type);
|
||||
os << "\" to values of type ";
|
||||
type::print(os, type_of(arg1));
|
||||
types::print(os, type_of(arg1));
|
||||
os << " and ";
|
||||
type::print(os, type_of(arg2));
|
||||
types::print(os, type_of(arg2));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -404,15 +396,15 @@ namespace pslang::interpreter
|
|||
auto type1 = type_of(arg1);
|
||||
auto type2 = type_of(arg2);
|
||||
|
||||
if (!type::equal(type1, type2))
|
||||
if (!types::equal(type1, type2))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Cannot apply binary operator \"";
|
||||
print(os, binary_operation.type);
|
||||
os << "\" to values of type ";
|
||||
type::print(os, type1);
|
||||
types::print(os, type1);
|
||||
os << " and ";
|
||||
type::print(os, type2);
|
||||
types::print(os, type2);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -422,30 +414,30 @@ namespace pslang::interpreter
|
|||
throw std::runtime_error("eval(binary_operation) for different argument types not implemented");
|
||||
}
|
||||
|
||||
value cast_impl(unit_value const & value, type::type const & type)
|
||||
value cast_impl(unit_value const & value, types::type const & type)
|
||||
{
|
||||
if (type::equal(type, type::unit_type{}))
|
||||
if (types::equal(type, types::unit_type{}))
|
||||
return value;
|
||||
|
||||
throw std::runtime_error("Cannot cast unit type to anything");
|
||||
}
|
||||
|
||||
value cast_impl(array_value const & value, type::type const & type)
|
||||
value cast_impl(array_value const & value, types::type const & type)
|
||||
{
|
||||
if (type::equal(type, type_of(value)))
|
||||
if (types::equal(type, type_of(value)))
|
||||
return value;
|
||||
|
||||
throw std::runtime_error("Cannot cast array type to anything");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value cast_impl(primitive_value_base<T> const & value, type::unit_type const &)
|
||||
value cast_impl(primitive_value_base<T> const & value, types::unit_type const &)
|
||||
{
|
||||
throw std::runtime_error("Cannot cast anything to unit type");
|
||||
}
|
||||
|
||||
template <typename T, typename H>
|
||||
value cast_impl(primitive_value_base<T> const & value, type::primitive_type_base<H> const & type)
|
||||
value cast_impl(primitive_value_base<T> const & value, types::primitive_type_base<H> const & type)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, H>)
|
||||
{
|
||||
|
|
@ -458,50 +450,50 @@ namespace pslang::interpreter
|
|||
|
||||
std::ostringstream os;
|
||||
os << "Cannot cast value of type ";
|
||||
type::print(os, type_of(primitive_value(value)));
|
||||
types::print(os, type_of(primitive_value(value)));
|
||||
os << " to type ";
|
||||
type::print(os, type::primitive_type(type));
|
||||
types::print(os, types::primitive_type(type));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value cast_impl(primitive_value_base<T> const & value, type::primitive_type const & type)
|
||||
value cast_impl(primitive_value_base<T> const & value, types::primitive_type const & type)
|
||||
{
|
||||
return std::visit([&](auto const & type){ return cast_impl(value, type); }, type);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value cast_impl(primitive_value_base<T> const &, type::array_type const &)
|
||||
value cast_impl(primitive_value_base<T> const &, types::array_type const &)
|
||||
{
|
||||
throw std::runtime_error("Cannot cast anything to array type");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value cast_impl(primitive_value_base<T> const &, type::function_type const &)
|
||||
value cast_impl(primitive_value_base<T> const &, types::function_type const &)
|
||||
{
|
||||
throw std::runtime_error("Cannot cast anything to function type");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value cast_impl(primitive_value_base<T> const & value, type::type const & type)
|
||||
value cast_impl(primitive_value_base<T> const & value, types::type const & type)
|
||||
{
|
||||
return std::visit([&](auto const & type){ return cast_impl(value, type); }, type);
|
||||
}
|
||||
|
||||
value cast_impl(primitive_value const & value, type::type const & type)
|
||||
value cast_impl(primitive_value const & value, types::type const & type)
|
||||
{
|
||||
return std::visit([&](auto const & value){ return cast_impl(value, type); }, value);
|
||||
}
|
||||
|
||||
value cast_impl(struct_value const & value, type::type const & type)
|
||||
value cast_impl(struct_value const & value, types::type const & type)
|
||||
{
|
||||
if (type::equal(type, type::unit_type{}))
|
||||
if (types::equal(type, types::unit_type{}))
|
||||
return value;
|
||||
|
||||
throw std::runtime_error("Cannot cast struct type to anything");
|
||||
}
|
||||
|
||||
value cast_impl(function_value const &, type::type const &)
|
||||
value cast_impl(function_value const &, types::type const &)
|
||||
{
|
||||
throw std::runtime_error("Cannot cast function type to anything");
|
||||
}
|
||||
|
|
@ -509,7 +501,8 @@ namespace pslang::interpreter
|
|||
value eval_impl(context & context, ast::cast_operation const & cast_operation)
|
||||
{
|
||||
auto arg = eval(context, cast_operation.expression);
|
||||
return std::visit([&](auto const & value){ return cast_impl(value, *cast_operation.type); }, arg);
|
||||
auto type = resolve_type(context, *cast_operation.type);
|
||||
return std::visit([&](auto const & value){ return cast_impl(value, type); }, arg);
|
||||
}
|
||||
|
||||
value eval_impl(context & context, ast::function_call const & function_call)
|
||||
|
|
@ -537,13 +530,13 @@ namespace pslang::interpreter
|
|||
for (std::size_t i = 0; i < args.size(); ++i)
|
||||
{
|
||||
auto actual_type = type_of(args[i]);
|
||||
if (!type::equal(actual_type, *jt->second.fields[i].type))
|
||||
if (!types::equal(actual_type, *jt->second.fields[i].type))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Cannot create struct \"" << identifier->name << "\": field " << jt->second.fields[i].name << " expects type ";
|
||||
type::print(os, *jt->second.fields[i].type);
|
||||
types::print(os, *jt->second.fields[i].type);
|
||||
os << " but actual type is ";
|
||||
type::print(os, actual_type);
|
||||
types::print(os, actual_type);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -551,7 +544,7 @@ namespace pslang::interpreter
|
|||
}
|
||||
|
||||
return struct_value{
|
||||
.struct_type = std::make_unique<type::type>(resolve_type(context, type::identifier{identifier->name})),
|
||||
.struct_type = std::make_unique<types::type>(types::named_type{.name = identifier->name, .level = identifier->level}),
|
||||
.fields = std::move(fields),
|
||||
};
|
||||
}
|
||||
|
|
@ -576,13 +569,13 @@ namespace pslang::interpreter
|
|||
for (std::size_t i = 0; i < args.size(); ++i)
|
||||
{
|
||||
auto actual_type = type_of(args[i]);
|
||||
if (!type::equal(actual_type, *fvalue->arguments[i].type))
|
||||
if (!types::equal(actual_type, *fvalue->arguments[i].type))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Cannot call function: argument #" << (i + 1) << " expects type ";
|
||||
type::print(os, *fvalue->arguments[i].type);
|
||||
types::print(os, *fvalue->arguments[i].type);
|
||||
os << " but actual type is ";
|
||||
type::print(os, actual_type);
|
||||
types::print(os, actual_type);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
}
|
||||
|
|
@ -598,13 +591,13 @@ namespace pslang::interpreter
|
|||
exec(context, fvalue->statements);
|
||||
|
||||
auto actual_return_type = type_of(context.scope_stack.back().return_value);
|
||||
if (!type::equal(actual_return_type, *expected_return_type))
|
||||
if (!types::equal(actual_return_type, *expected_return_type))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Error returning from function: expected return type is ";
|
||||
type::print(os, *expected_return_type);
|
||||
types::print(os, *expected_return_type);
|
||||
os << " but actual type is ";
|
||||
type::print(os, actual_return_type);
|
||||
types::print(os, actual_return_type);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -625,23 +618,23 @@ namespace pslang::interpreter
|
|||
if (array.elements.empty())
|
||||
throw std::runtime_error("Internal error: array ast node cannot have zero elements");
|
||||
|
||||
type::type_ptr element_type;
|
||||
types::type_ptr element_type;
|
||||
std::vector<value_ptr> elements;
|
||||
for (std::size_t i = 0; i < array.elements.size(); ++i)
|
||||
{
|
||||
auto element = std::make_unique<value>(eval(context, array.elements[i]));
|
||||
if (i == 0)
|
||||
element_type = std::make_unique<type::type>(type_of(*element));
|
||||
element_type = std::make_unique<types::type>(type_of(*element));
|
||||
else
|
||||
{
|
||||
auto new_type = type_of(*element);
|
||||
if (!type::equal(*element_type, new_type))
|
||||
if (!types::equal(*element_type, new_type))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Error forming array: inferred element type is ";
|
||||
type::print(os, *element_type);
|
||||
types::print(os, *element_type);
|
||||
os << " but element #" << i << " type is ";
|
||||
type::print(os, new_type);
|
||||
types::print(os, new_type);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
}
|
||||
|
|
@ -664,7 +657,7 @@ namespace pslang::interpreter
|
|||
|
||||
std::ostringstream os;
|
||||
os << "Cannot index into a non-array of type ";
|
||||
type::print(os, type_of(array));
|
||||
types::print(os, type_of(array));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -678,14 +671,14 @@ namespace pslang::interpreter
|
|||
|
||||
std::ostringstream os;
|
||||
os << "Struct ";
|
||||
type::print(os, type_of(object));
|
||||
types::print(os, type_of(object));
|
||||
os << " has no field named \"" << field_access.field_name << "\"";
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << "Value of type ";
|
||||
type::print(os, type_of(object));
|
||||
types::print(os, type_of(object));
|
||||
os << " is not a struct";
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
|
@ -753,7 +746,7 @@ namespace pslang::interpreter
|
|||
|
||||
std::ostringstream os;
|
||||
os << "Cannot index into a non-array of type ";
|
||||
type::print(os, type_of(*array_ref));
|
||||
types::print(os, type_of(*array_ref));
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -767,14 +760,14 @@ namespace pslang::interpreter
|
|||
|
||||
std::ostringstream os;
|
||||
os << "Struct ";
|
||||
type::print(os, type_of(*object_ref));
|
||||
types::print(os, type_of(*object_ref));
|
||||
os << " has no field named \"" << field_access.field_name << "\"";
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << "Value of type ";
|
||||
type::print(os, type_of(*object_ref));
|
||||
types::print(os, type_of(*object_ref));
|
||||
os << " is not a struct";
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
|
@ -786,7 +779,7 @@ namespace pslang::interpreter
|
|||
|
||||
}
|
||||
|
||||
type::type resolve_type(context & context, type::type const & type)
|
||||
types::type resolve_type(context & context, ast::type const & type)
|
||||
{
|
||||
return resolve_type_impl(context, type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include <pslang/interpreter/exec.hpp>
|
||||
#include <pslang/interpreter/eval.hpp>
|
||||
#include <pslang/ast/statement.hpp>
|
||||
#include <pslang/type/print.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
|
@ -43,13 +43,13 @@ namespace pslang::interpreter
|
|||
auto ref = eval_ref(context, assignment.lhs);
|
||||
|
||||
auto existing_type = type_of(*ref);
|
||||
if (!type::equal(existing_type, new_type))
|
||||
if (!types::equal(existing_type, new_type))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Cannot assign a value of type ";
|
||||
type::print(os, new_type);
|
||||
types::print(os, new_type);
|
||||
os << " to a variable of type ";
|
||||
type::print(os, existing_type);
|
||||
types::print(os, existing_type);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
|
|
@ -67,13 +67,13 @@ namespace pslang::interpreter
|
|||
{
|
||||
auto expected_type = resolve_type(context, *variable_declaration.type);
|
||||
auto actual_type = type_of(value);
|
||||
if (!type::equal(expected_type, actual_type))
|
||||
if (!types::equal(expected_type, actual_type))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Cannot initialize a variable of type ";
|
||||
type::print(os, expected_type);
|
||||
types::print(os, expected_type);
|
||||
os << " with an expression of type ";
|
||||
type::print(os, actual_type);
|
||||
types::print(os, actual_type);
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
}
|
||||
|
|
@ -105,11 +105,11 @@ namespace pslang::interpreter
|
|||
{
|
||||
auto value = eval(context, block.condition);
|
||||
auto actual_type = type_of(value);
|
||||
if (!type::equal(actual_type, type::primitive_type{type::bool_type{}}))
|
||||
if (!types::equal(actual_type, types::primitive_type{types::bool_type{}}))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Expected type bool, got type ";
|
||||
type::print(os, actual_type);
|
||||
types::print(os, actual_type);
|
||||
os << " in if block condition";
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
|
@ -133,11 +133,11 @@ namespace pslang::interpreter
|
|||
{
|
||||
auto value = eval(context, while_block.condition);
|
||||
auto actual_type = type_of(value);
|
||||
if (!type::equal(actual_type, type::primitive_type{type::bool_type{}}))
|
||||
if (!types::equal(actual_type, types::primitive_type{types::bool_type{}}))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Expected type bool, got type ";
|
||||
type::print(os, actual_type);
|
||||
types::print(os, actual_type);
|
||||
os << " in while block condition";
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
|
@ -162,8 +162,8 @@ namespace pslang::interpreter
|
|||
function_value value;
|
||||
|
||||
for (auto const & argument : function_definition.arguments)
|
||||
value.arguments.push_back({.name = argument.name, .type = std::make_unique<type::type>(resolve_type(context, *argument.type))});
|
||||
value.return_type = std::make_unique<type::type>(resolve_type(context, *function_definition.return_type));
|
||||
value.arguments.push_back({.name = argument.name, .type = std::make_unique<types::type>(resolve_type(context, *argument.type))});
|
||||
value.return_type = std::make_unique<types::type>(resolve_type(context, *function_definition.return_type));
|
||||
value.statements = function_definition.statements;
|
||||
|
||||
scope.variables[function_definition.name] = {.category = ast::value_category::constant, .value = std::move(value)};
|
||||
|
|
@ -200,7 +200,7 @@ namespace pslang::interpreter
|
|||
{
|
||||
result.fields.push_back({
|
||||
.name = field.name,
|
||||
.type = std::make_unique<type::type>(resolve_type(context, *field.type)),
|
||||
.type = std::make_unique<types::type>(resolve_type(context, *field.type)),
|
||||
});
|
||||
}
|
||||
scope.structs[struct_definition.name] = std::move(result);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <pslang/interpreter/value.hpp>
|
||||
#include <pslang/type/print.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
|
|
@ -9,42 +9,42 @@ namespace pslang::interpreter
|
|||
namespace
|
||||
{
|
||||
|
||||
type::type type_of_impl(unit_value const &)
|
||||
types::type type_of_impl(unit_value const &)
|
||||
{
|
||||
return type::unit_type{};
|
||||
return types::unit_type{};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
type::type type_of_impl(primitive_value_base<T> const &)
|
||||
types::type type_of_impl(primitive_value_base<T> const &)
|
||||
{
|
||||
return type::primitive_type(type::primitive_type_base<T>{});
|
||||
return types::primitive_type(types::primitive_type_base<T>{});
|
||||
}
|
||||
|
||||
type::type type_of_impl(primitive_value const & value)
|
||||
types::type type_of_impl(primitive_value const & value)
|
||||
{
|
||||
return std::visit([](auto const & value){ return type_of_impl(value); }, value);
|
||||
}
|
||||
|
||||
type::type type_of_impl(array_value const & value)
|
||||
types::type type_of_impl(array_value const & value)
|
||||
{
|
||||
return type::array_type{.element_type = value.element_type, .size = value.elements.size()};
|
||||
return types::array_type{.element_type = value.element_type, .size = value.elements.size()};
|
||||
}
|
||||
|
||||
type::type type_of_impl(struct_value const & value)
|
||||
types::type type_of_impl(struct_value const & value)
|
||||
{
|
||||
return *value.struct_type;
|
||||
}
|
||||
|
||||
type::type type_of_impl(function_value const & value)
|
||||
types::type type_of_impl(function_value const & value)
|
||||
{
|
||||
type::function_type result;
|
||||
types::function_type result;
|
||||
for (auto const & argument : value.arguments)
|
||||
result.arguments.push_back(argument.type);
|
||||
result.result = value.return_type;
|
||||
return result;
|
||||
}
|
||||
|
||||
type::type type_of_impl(value const & value)
|
||||
types::type type_of_impl(value const & value)
|
||||
{
|
||||
return std::visit([](auto const & value){ return type_of_impl(value); }, value);
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ namespace pslang::interpreter
|
|||
|
||||
}
|
||||
|
||||
type::type type_of(value const & value)
|
||||
types::type type_of(value const & value)
|
||||
{
|
||||
return type_of_impl(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,8 @@
|
|||
|
||||
%code requires {
|
||||
|
||||
#include <pslang/ast/statement.hpp>
|
||||
#include <pslang/ast/location.hpp>
|
||||
#include <pslang/parser/indented_statement.hpp>
|
||||
#include <pslang/ast/statement.hpp>
|
||||
|
||||
namespace pslang::parser {
|
||||
|
||||
|
|
@ -149,13 +148,13 @@ template <typename T>
|
|||
%type <std::vector<ast::function_definition::argument>> function_definition_argument_list
|
||||
%type <std::vector<ast::function_definition::argument>> nonempty_function_definition_argument_list
|
||||
%type <ast::function_definition::argument> function_definition_single_argument
|
||||
%type <type::type_ptr> function_return_type
|
||||
%type <ast::type_ptr> function_return_type
|
||||
%type <ast::variable_declaration> variable_declaration
|
||||
%type <ast::value_category> variable_keyword
|
||||
%type <type::type> type_expression
|
||||
%type <type::primitive_type> primitive_type
|
||||
%type <std::vector<type::type_ptr>> function_paren_type_list
|
||||
%type <std::vector<type::type_ptr>> two_or_more_type_list
|
||||
%type <ast::type> type_expression
|
||||
%type <types::primitive_type> primitive_type
|
||||
%type <std::vector<ast::type_ptr>> function_paren_type_list
|
||||
%type <std::vector<ast::type_ptr>> two_or_more_type_list
|
||||
%type <ast::expression> expression
|
||||
%type <ast::expression> postfix_expression
|
||||
%type <ast::expression> base_expression
|
||||
|
|
@ -192,7 +191,7 @@ statement
|
|||
| return expression { $$ = ast::return_statement{std::make_unique<ast::expression>($2), @$}; }
|
||||
| return { $$ = ast::return_statement{nullptr, @$}; }
|
||||
| struct name colon { $$ = ast::struct_definition{$2, {}, @$}; }
|
||||
| name colon type_expression { $$ = ast::field_definition{$1, std::make_unique<type::type>($3), @$}; }
|
||||
| name colon type_expression { $$ = ast::field_definition{$1, std::make_unique<ast::type>($3), @$}; }
|
||||
;
|
||||
|
||||
function_definition_argument_list
|
||||
|
|
@ -206,17 +205,17 @@ nonempty_function_definition_argument_list
|
|||
;
|
||||
|
||||
function_definition_single_argument
|
||||
: name colon type_expression { $$ = ast::function_definition::argument{$1, std::make_unique<type::type>($3), @$}; }
|
||||
: name colon type_expression { $$ = ast::function_definition::argument{$1, std::make_unique<ast::type>($3), @$}; }
|
||||
;
|
||||
|
||||
function_return_type
|
||||
: arrow type_expression { $$ = std::make_unique<type::type>($2); }
|
||||
| %empty { $$ = std::make_unique<type::type>(type::unit_type{}); }
|
||||
: arrow type_expression { $$ = std::make_unique<ast::type>($2); }
|
||||
| %empty { $$ = std::make_unique<ast::type>(types::unit_type{}); }
|
||||
;
|
||||
|
||||
variable_declaration
|
||||
: variable_keyword name assignment expression { $$ = ast::variable_declaration{$1, $2, nullptr, std::make_unique<ast::expression>($4), @$}; }
|
||||
| variable_keyword name colon type_expression assignment expression { $$ = ast::variable_declaration{$1, $2, std::make_unique<type::type>($4), std::make_unique<ast::expression>($6), @$}; }
|
||||
| variable_keyword name colon type_expression assignment expression { $$ = ast::variable_declaration{$1, $2, std::make_unique<ast::type>($4), std::make_unique<ast::expression>($6), @$}; }
|
||||
;
|
||||
|
||||
variable_keyword
|
||||
|
|
@ -226,37 +225,37 @@ variable_keyword
|
|||
;
|
||||
|
||||
type_expression
|
||||
: unit { $$ = type::type(type::unit_type{}); }
|
||||
| primitive_type { $$ = type::type($1); }
|
||||
| name { $$ = type::identifier{$1}; }
|
||||
| type_expression lbracket lit_i32 rbracket { $$ = type::array_type{std::make_unique<type::type>($1), std::stoull($3)}; }
|
||||
| type_expression arrow type_expression { std::vector<type::type_ptr> args; args.push_back(std::make_unique<type::type>($1)); $$ = type::function_type{std::move(args), std::make_unique<type::type>($3)}; }
|
||||
| lparen function_paren_type_list rparen arrow type_expression { $$ = type::function_type{$2, std::make_unique<type::type>($5)}; }
|
||||
: unit { $$ = types::unit_type{}; }
|
||||
| primitive_type { $$ = ast::type($1); }
|
||||
| name { $$ = ast::type_identifier{$1}; }
|
||||
| type_expression lbracket lit_i32 rbracket { $$ = ast::array_type{std::make_unique<ast::type>($1), std::stoull($3)}; }
|
||||
| type_expression arrow type_expression { std::vector<ast::type_ptr> args; args.push_back(std::make_unique<ast::type>($1)); $$ = ast::function_type{std::move(args), std::make_unique<ast::type>($3)}; }
|
||||
| lparen function_paren_type_list rparen arrow type_expression { $$ = ast::function_type{$2, std::make_unique<ast::type>($5)}; }
|
||||
| lparen type_expression rparen { $$ = $2; }
|
||||
;
|
||||
|
||||
primitive_type
|
||||
: bool { $$ = type::bool_type{}; }
|
||||
| i8 { $$ = type::i8_type{}; }
|
||||
| u8 { $$ = type::u8_type{}; }
|
||||
| i16 { $$ = type::i16_type{}; }
|
||||
| u16 { $$ = type::u16_type{}; }
|
||||
| i32 { $$ = type::i32_type{}; }
|
||||
| u32 { $$ = type::u32_type{}; }
|
||||
| i64 { $$ = type::i64_type{}; }
|
||||
| u64 { $$ = type::u64_type{}; }
|
||||
| f32 { $$ = type::f32_type{}; }
|
||||
| f64 { $$ = type::f64_type{}; }
|
||||
: bool { $$ = types::bool_type{}; }
|
||||
| i8 { $$ = types::i8_type{}; }
|
||||
| u8 { $$ = types::u8_type{}; }
|
||||
| i16 { $$ = types::i16_type{}; }
|
||||
| u16 { $$ = types::u16_type{}; }
|
||||
| i32 { $$ = types::i32_type{}; }
|
||||
| u32 { $$ = types::u32_type{}; }
|
||||
| i64 { $$ = types::i64_type{}; }
|
||||
| u64 { $$ = types::u64_type{}; }
|
||||
| f32 { $$ = types::f32_type{}; }
|
||||
| f64 { $$ = types::f64_type{}; }
|
||||
;
|
||||
|
||||
function_paren_type_list
|
||||
: %empty { std::vector<type::type_ptr> tmp; $$ = std::move(tmp); }
|
||||
: %empty { std::vector<ast::type_ptr> tmp; $$ = std::move(tmp); }
|
||||
| two_or_more_type_list { $$ = $1; }
|
||||
;
|
||||
|
||||
two_or_more_type_list
|
||||
: type_expression comma type_expression { std::vector<type::type_ptr> tmp; tmp.push_back(std::make_unique<type::type>($1)); tmp.push_back(std::make_unique<type::type>($3)); $$ = std::move(tmp); }
|
||||
| two_or_more_type_list comma type_expression { auto tmp = $1; tmp.push_back(std::make_unique<type::type>($3)); $$ = std::move(tmp); }
|
||||
: type_expression comma type_expression { std::vector<ast::type_ptr> tmp; tmp.push_back(std::make_unique<ast::type>($1)); tmp.push_back(std::make_unique<ast::type>($3)); $$ = std::move(tmp); }
|
||||
| two_or_more_type_list comma type_expression { auto tmp = $1; tmp.push_back(std::make_unique<ast::type>($3)); $$ = std::move(tmp); }
|
||||
;
|
||||
|
||||
expression
|
||||
|
|
@ -269,7 +268,7 @@ expression
|
|||
| expression greater expression { $$ = ast::binary_operation{ast::binary_operation_type::greater, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||
| expression less_equals expression { $$ = ast::binary_operation{ast::binary_operation_type::less_equals, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||
| expression greater_equals expression { $$ = ast::binary_operation{ast::binary_operation_type::greater_equals, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||
| expression as type_expression { $$ = ast::cast_operation{ std::make_unique<ast::expression>($1), std::make_unique<type::type>($3), @$ }; }
|
||||
| expression as type_expression { $$ = ast::cast_operation{ std::make_unique<ast::expression>($1), std::make_unique<ast::type>($3), @$ }; }
|
||||
| minus expression %prec UMINUS { $$ = ast::unary_operation{ast::unary_operation_type::negation, std::make_unique<ast::expression>($2), @$ }; }
|
||||
| expression plus expression { $$ = ast::binary_operation{ast::binary_operation_type::addition, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||
| expression minus expression { $$ = ast::binary_operation{ast::binary_operation_type::subtraction, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
file(GLOB_RECURSE PSLANG_TYPE_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp")
|
||||
file(GLOB_RECURSE PSLANG_TYPE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
|
||||
|
||||
add_library(pslang-type STATIC ${PSLANG_TYPE_HEADERS} ${PSLANG_TYPE_SOURCES})
|
||||
target_include_directories(pslang-type PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/type/unit.hpp>
|
||||
#include <pslang/type/primitive.hpp>
|
||||
#include <pslang/type/array.hpp>
|
||||
#include <pslang/type/function.hpp>
|
||||
#include <pslang/type/identifier.hpp>
|
||||
#include <pslang/type/type_fwd.hpp>
|
||||
|
||||
#include <variant>
|
||||
|
||||
namespace pslang::type
|
||||
{
|
||||
|
||||
using type_impl = std::variant<
|
||||
unit_type,
|
||||
primitive_type,
|
||||
array_type,
|
||||
function_type,
|
||||
identifier
|
||||
>;
|
||||
|
||||
struct type
|
||||
: type_impl
|
||||
{
|
||||
using type_impl::type_impl;
|
||||
};
|
||||
|
||||
}
|
||||
5
libs/types/CMakeLists.txt
Normal file
5
libs/types/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
file(GLOB_RECURSE PSLANG_TYPES_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp")
|
||||
file(GLOB_RECURSE PSLANG_TYPES_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
|
||||
|
||||
add_library(pslang-types STATIC ${PSLANG_TYPES_HEADERS} ${PSLANG_TYPES_SOURCES})
|
||||
target_include_directories(pslang-types PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/type/type_fwd.hpp>
|
||||
#include <pslang/types/type_fwd.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
struct array_type
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/type/type_fwd.hpp>
|
||||
#include <pslang/types/type_fwd.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
struct function_type
|
||||
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
struct identifier
|
||||
struct named_type
|
||||
{
|
||||
std::string name;
|
||||
std::size_t level = 0;
|
||||
std::size_t level;
|
||||
};
|
||||
|
||||
inline bool operator == (identifier const & t1, identifier const & t2)
|
||||
inline bool operator == (named_type const & t1, named_type const & t2)
|
||||
{
|
||||
return (t1.level == t2.level) && (t1.name == t2.name);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include <variant>
|
||||
#include <cstdint>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/type/type_fwd.hpp>
|
||||
#include <pslang/types/type_fwd.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
void print(std::ostream & out, type const & type);
|
||||
29
libs/types/include/pslang/types/type.hpp
Normal file
29
libs/types/include/pslang/types/type.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/types/unit.hpp>
|
||||
#include <pslang/types/primitive.hpp>
|
||||
#include <pslang/types/array.hpp>
|
||||
#include <pslang/types/function.hpp>
|
||||
#include <pslang/types/named.hpp>
|
||||
#include <pslang/types/type_fwd.hpp>
|
||||
|
||||
#include <variant>
|
||||
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
using type_impl = std::variant<
|
||||
unit_type,
|
||||
primitive_type,
|
||||
array_type,
|
||||
function_type,
|
||||
named_type
|
||||
>;
|
||||
|
||||
struct type
|
||||
: type_impl
|
||||
{
|
||||
using type_impl::type_impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
struct type;
|
||||
|
|
@ -10,4 +10,5 @@ namespace pslang::type
|
|||
using type_ptr = std::shared_ptr<type>;
|
||||
|
||||
bool equal(type const & t1, type const & t2);
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
struct unit_type
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include <pslang/type/print.hpp>
|
||||
#include <pslang/type/type.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
#include <pslang/types/type.hpp>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
namespace
|
||||
|
|
@ -100,7 +100,7 @@ namespace pslang::type
|
|||
print(out, *type.result);
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, identifier const & type)
|
||||
void print_impl(std::ostream & out, named_type const & type)
|
||||
{
|
||||
out << type.name;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include <pslang/type/type.hpp>
|
||||
#include <pslang/types/type.hpp>
|
||||
|
||||
namespace pslang::type
|
||||
namespace pslang::types
|
||||
{
|
||||
|
||||
bool equal(type const & t1, type const & t2)
|
||||
Loading…
Add table
Reference in a new issue