diff --git a/deps/tree-sitter-lang b/deps/tree-sitter-lang
index 6b09331..1357783 160000
--- a/deps/tree-sitter-lang
+++ b/deps/tree-sitter-lang
@@ -1 +1 @@
-Subproject commit 6b093311dfb371cf67a218a8c97779ae5e15e234
+Subproject commit 1357783074e77c2c5ddcec16e90cf59940dabd9d
diff --git a/etc/kate_highlighting_lang.xml b/etc/kate_highlighting_lang.xml
index b076662..a93b7e4 100644
--- a/etc/kate_highlighting_lang.xml
+++ b/etc/kate_highlighting_lang.xml
@@ -64,7 +64,7 @@
-
+
diff --git a/include/builders/type_builders.hpp b/include/builders/type_builders.hpp
index c39607c..1afce88 100644
--- a/include/builders/type_builders.hpp
+++ b/include/builders/type_builders.hpp
@@ -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);
diff --git a/include/builtin_types.hpp b/include/builtin_types.hpp
index d9f0eb5..854a222 100644
--- a/include/builtin_types.hpp
+++ b/include/builtin_types.hpp
@@ -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 get_parameters_count(Type type) {
// -- containers
case Type::TUPLE:
case Type::VARIANT:
+ case Type::FUNCTION:
return std::nullopt;
case Type::ARRAY:
case Type::OPTIONAL:
diff --git a/include/expression_type_check.hpp b/include/expression_type_check.hpp
index 5c3f266..caa6ceb 100644
--- a/include/expression_type_check.hpp
+++ b/include/expression_type_check.hpp
@@ -3,6 +3,7 @@
#include "expression_nodes.hpp"
#include "sources_manager.hpp"
#include "type_nodes.hpp"
+#include "utils.hpp"
#include
@@ -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 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 brought_type;
std::optional returned_type;
+
+private:
+ std::vector> contexts_ = {
+ {}};
};
nodes::TypeCheckResult
diff --git a/include/nodes/type_nodes.hpp b/include/nodes/type_nodes.hpp
index 26b46fd..c661c87 100644
--- a/include/nodes/type_nodes.hpp
+++ b/include/nodes/type_nodes.hpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
@@ -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 unit_type_id;
-
+ // TODO
+ // std::unordered_map named_local_types_;
+ std::unordered_map primitive_type_ids_;
std::vector 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
diff --git a/include/tokens.hpp b/include/tokens.hpp
index 52c0fce..d64480b 100644
--- a/include/tokens.hpp
+++ b/include/tokens.hpp
@@ -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) {
diff --git a/src/builders/statement_builders.cpp b/src/builders/statement_builders.cpp
index e8f6e69..b6a5178 100644
--- a/src/builders/statement_builders.cpp
+++ b/src/builders/statement_builders.cpp
@@ -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:
diff --git a/src/builders/type_builders.cpp b/src/builders/type_builders.cpp
index 64aae9a..1ac9fc7 100644
--- a/src/builders/type_builders.cpp
+++ b/src/builders/type_builders.cpp
@@ -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) {
diff --git a/tests/test.langexp b/tests/test.langexp
index e5c2e39..49ba767 100644
--- a/tests/test.langexp
+++ b/tests/test.langexp
@@ -226,7 +226,7 @@ result_func! 'a 'b -> 'c -> 'd = ?? 'a == 0 => error "some error" !!=> ('c := 'a
tuple_argument_test 'x : (A & B & C) = do_something;
// ((A1 & A2) | B | C) same to Variant[Tuple[A1 A2] B C]
-variant_argument_test 'x : ((A1 & A2) | B | C) = do_something;
+variant_argument_test 'x : ( (A1 & A2) | B | C) = do_something;
literals_test = {
%float_number_literal := 1.0f;
@@ -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;