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