function type

This commit is contained in:
ProgramSnail 2023-08-14 18:14:05 +03:00
parent 7f3dfd71a1
commit fa01d36a84
10 changed files with 87 additions and 64 deletions

@ -1 +1 @@
Subproject commit 6b093311dfb371cf67a218a8c97779ae5e15e234
Subproject commit 1357783074e77c2c5ddcec16e90cf59940dabd9d

View file

@ -64,7 +64,7 @@
<RegExpr String="\b[0-9]+[il]?\b" attribute="Decimal" context="#stay"/>
<RegExpr String="&quot;([^\\&quot;]|(\\.))*&quot;u?" attribute="String" context="#stay" />
<RegExpr String="((?&lt;![\+\\\-\*/%\^\!\?\|&amp;,&lt;>=\.])((\.+)|([\+\\\-\*/%\^\!\?\|&amp;,&lt;>=]+\.?\.?\.?)))|(\|)" attribute="Operator" context="#stay"/>
<RegExpr String="((?&lt;![\+\\\-\*/%\^\!\?\|&amp;,&lt;>=\.])((\.+)|([\+\\\-\*/%\^\!\?\|&amp;,&lt;>=]+\.?\.?\.?)))|(\|)|(\[\[)|(\]\])|(\(\()|(\)\))" attribute="Operator" context="#stay"/>
<RegExpr String="([a-z_][a-z0-9_]*\.)*(([a-z_][a-z0-9_]*)|_)(?![a-z0-9_])" attribute="Name" context="#stay"/>

View file

@ -14,6 +14,9 @@ nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_function_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_array_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);

View file

@ -13,6 +13,8 @@ const static std::string TUPLE_IDENTIFIER = "Tuple";
const static std::string VARIANT_IDENTIFIER = "Variant";
const static std::string FUNCTION_IDENTIFIER = "Function";
const static std::string ARRAY_IDENTIFIER = "Array";
const static std::string OPTIONAL_IDENTIFIER = "Optional";
@ -50,6 +52,7 @@ enum class Type {
// -- containers
TUPLE,
VARIANT,
FUNCTION,
ARRAY,
OPTIONAL,
RESULT,
@ -75,6 +78,8 @@ inline std::string to_string(Type type) {
return TUPLE_IDENTIFIER;
case Type::VARIANT:
return VARIANT_IDENTIFIER;
case Type::FUNCTION:
return FUNCTION_IDENTIFIER;
case Type::ARRAY:
return ARRAY_IDENTIFIER;
case Type::OPTIONAL:
@ -118,6 +123,7 @@ inline Type to_type(const std::string &str) {
// -- containers
builtin_types[TUPLE_IDENTIFIER] = Type::TUPLE;
builtin_types[VARIANT_IDENTIFIER] = Type::VARIANT;
builtin_types[FUNCTION_IDENTIFIER] = Type::FUNCTION;
builtin_types[ARRAY_IDENTIFIER] = Type::ARRAY;
builtin_types[OPTIONAL_IDENTIFIER] = Type::OPTIONAL;
builtin_types[RESULT_IDENTIFIER] = Type::RESULT;
@ -161,6 +167,7 @@ inline std::optional<size_t> get_parameters_count(Type type) {
// -- containers
case Type::TUPLE:
case Type::VARIANT:
case Type::FUNCTION:
return std::nullopt;
case Type::ARRAY:
case Type::OPTIONAL:

View file

@ -3,6 +3,7 @@
#include "expression_nodes.hpp"
#include "sources_manager.hpp"
#include "type_nodes.hpp"
#include "utils.hpp"
#include <optional>
@ -10,9 +11,46 @@
namespace type_check {
struct State {
class State {
public:
bool insert_variable(const std::string &name, nodes::TypeProxy type) {
if (contexts_.size() == 0) {
error_handling::handle_general_error(
"Insert variable into contexts_ with zero elements in State");
}
return contexts_.back().insert({name, type}).second;
}
std::optional<nodes::TypeProxy> find_variable(const std::string &name) {
for (ssize_t i = contexts_.size(); i >= 0; --i) {
auto iter = contexts_[i].find(name);
if (iter != contexts_[i].end()) {
return iter->second;
}
}
return std::nullopt;
}
void enter_context() { contexts_.emplace_back(); }
void exit_context() {
if (contexts_.size() == 0) {
error_handling::handle_general_error(
"Pop from contexts_ with zero elements in State");
}
contexts_.pop_back();
}
public:
std::optional<nodes::TypeProxy> brought_type;
std::optional<nodes::TypeProxy> returned_type;
private:
std::vector<std::unordered_map<std::string, nodes::TypeProxy>> contexts_ = {
{}};
};
nodes::TypeCheckResult

View file

@ -9,6 +9,7 @@
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include <vector>
@ -207,10 +208,11 @@ class TypeStorage {
public:
TypeProxy primitive_type(builtin::types::Type type) {
if (unit_type_id.has_value()) {
return TypeProxy(*this, unit_type_id.value());
auto iter = primitive_type_ids_.find(type);
if (iter != primitive_type_ids_.end()) {
return TypeProxy(*this, iter->second);
} else {
unit_type_id = storage_.size();
primitive_type_ids_[type] = storage_.size();
return add_type(Type(Identifier(Node(), Identifier::SIMPLE_TYPE,
builtin::types::to_string(type))));
}
@ -251,72 +253,27 @@ public:
return TypeProxy(*this, storage_.size() - 1);
}
// TODO:
// bool try_resolve_all_generic_names
// bool add_generic_type
// bool add_local_type
// // add local type requirement
// // deduce generic type
// void clear_local_types
// ...
private:
Type *get_type(size_t id) { return &storage_.at(id); }
const Type *get_type(size_t id) const { return &storage_.at(id); }
private:
std::optional<size_t> unit_type_id;
// TODO
// std::unordered_map<std::string, size_t> named_local_types_;
std::unordered_map<builtin::types::Type, size_t> primitive_type_ids_;
std::vector<Type> storage_;
};
// class ModifiedTypeProxy {
// public:
// ModifiedTypeProxy(nodes::TypeProxy type,
// nodes::Modifier modifier = nodes::Modifier::NONE)
// : type_(type), modifier_(modifier) {}
//
// //
//
// nodes::Modifier get_modifier() const { return modifier_; }
//
// void set_modifier(nodes::Modifier modifier) { modifier_ = modifier; }
//
// //
//
// nodes::Type *get_type() { return type_.get(); }
//
// const nodes::Type *get_type() const { return type_.get(); }
//
// const nodes::TypeProxy get_type_proxy() const { return type_; }
//
// //
//
// bool operator==(const ModifiedTypeProxy &other) const {
// return *type_.get() == *other.type_.get() && modifier_ ==
// other.modifier_;
// }
//
// bool operator!=(const ModifiedTypeProxy &other) const {
// return !(*this == other);
// }
//
// //
//
// bool operator<(const ModifiedTypeProxy &other) const {
// return *type_.get() < *other.type_.get() ||
// (*type_.get() == *other.type_.get() && modifier_ <
// other.modifier_);
// }
//
// bool operator>(const ModifiedTypeProxy &other) const { return other <
// *this; }
//
// bool operator<=(const ModifiedTypeProxy &other) const {
// return !operator>(other);
// }
//
// bool operator>=(const ModifiedTypeProxy &other) const {
// return !operator<(other);
// }
//
// private:
// nodes::TypeProxy type_;
// nodes::Modifier modifier_;
// };
class TypeCheckResult {
public:
// for invalid type

View file

@ -54,6 +54,7 @@ enum class Type {
VARIANT_TYPE,
TUPLE_TYPE,
FUNCTION_TYPE,
ARRAY_TYPE,
REFERENCE_TYPE,
MODIFIED_TYPE,
@ -149,6 +150,7 @@ const static std::string LAMBDA = "lambda";
const static std::string VARIANT_TYPE = "variant_type";
const static std::string TUPLE_TYPE = "tuple_type";
const static std::string FUNCTION_TYPE = "function_type";
const static std::string ARRAY_TYPE = "array_type";
const static std::string REFERENCE_TYPE = "reference_type";
const static std::string MODIFIED_TYPE = "modified_type";
@ -242,6 +244,8 @@ inline Type string_to_type(const std::string &str) {
return Type::VARIANT_TYPE;
} else if (str == TUPLE_TYPE) {
return Type::TUPLE_TYPE;
} else if (str == FUNCTION_TYPE) {
return Type::FUNCTION_TYPE;
} else if (str == ARRAY_TYPE) {
return Type::ARRAY_TYPE;
} else if (str == REFERENCE_TYPE) {

View file

@ -382,6 +382,7 @@ nodes::FunctionDefinition build_function_definition(
break;
case tokens::Type::VARIANT_TYPE:
case tokens::Type::TUPLE_TYPE:
case tokens::Type::FUNCTION_TYPE:
case tokens::Type::ARRAY_TYPE:
case tokens::Type::REFERENCE_TYPE:
case tokens::Type::MODIFIED_TYPE:

View file

@ -23,6 +23,8 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
return build_variant_type(parser_node, type_storage);
case tokens::Type::TUPLE_TYPE:
return build_tuple_type(parser_node, type_storage);
case tokens::Type::FUNCTION_TYPE:
return build_function_type(parser_node, type_storage);
case tokens::Type::ARRAY_TYPE:
return build_array_type(parser_node, type_storage);
case tokens::Type::REFERENCE_TYPE:
@ -78,6 +80,13 @@ nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
builtin::types::Type::TUPLE);
}
// '((' (annotation? type)+ '))'
nodes::TypeProxy build_function_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
return build_container_type(parser_node, type_storage,
builtin::types::Type::FUNCTION);
}
// '[[' type ']]'
nodes::TypeProxy build_array_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {

View file

@ -242,3 +242,7 @@ literals_test = {
%unit_literal := ();
%null_literal := null;
}
array_argument_test 'x : [[ Int ]] = do_something;
functional_arguments_test 'x 'y : (( Int -> Int )) (( Float <- Float -> Float )) = do_something;