mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
expression builders finished, type builders started
This commit is contained in:
parent
6682e0beb1
commit
535d8d26c3
12 changed files with 909 additions and 76 deletions
2
deps/tree-sitter-lang
vendored
2
deps/tree-sitter-lang
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 567f75620da9609ee530442191aa4c1e18e7b9b4
|
||||
Subproject commit 39f31b901dd3f77f33ad7d047ac78d2b94d7ca1d
|
||||
130
etc/kate_highlighting_lang.xml
Normal file
130
etc/kate_highlighting_lang.xml
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "language.dtd">
|
||||
<language name="langexp" version="1" kateversion="5.0" section="Sources" extensions="*.langexp" mimetype="text/langexp" priority="5">
|
||||
<highlighting>
|
||||
<list name="controlflow">
|
||||
<item>if</item>
|
||||
<item>elif</item>
|
||||
<item>else</item>
|
||||
<item>for</item>
|
||||
<item>loop</item>
|
||||
<item>do</item>
|
||||
<item>break</item>
|
||||
<item>continue</item>
|
||||
<item>return</item>
|
||||
<item>bring</item>
|
||||
</list>
|
||||
<list name="keywords">
|
||||
<item>out</item>
|
||||
<item>in</item>
|
||||
<item>ref</item>
|
||||
<item>let</item>
|
||||
<item>var</item>
|
||||
<item>exec</item>
|
||||
<item>test</item>
|
||||
<item>example</item>
|
||||
</list>
|
||||
<list name="constants">
|
||||
<item>null</item>
|
||||
<item>true</item>
|
||||
<item>false</item>
|
||||
<item>this</item>
|
||||
<item>This</item>
|
||||
</list>
|
||||
<contexts>
|
||||
<context attribute="Normal Text" lineEndContext="#stay" name="Normal">
|
||||
<DetectSpaces/>
|
||||
<keyword String="controlflow" attribute="Control Flow" context="#stay"/>
|
||||
<keyword String="keywords" attribute="Keyword" context="#stay"/>
|
||||
<keyword String="constants" attribute="Constant" context="#stay"/>
|
||||
<Detect2Chars char="/" char1="/" attribute="Comment" context="Comment"/>
|
||||
<RegExpr String="\b[0-9]+\.[0-9]+\b" attribute="Float" context="#stay"/>
|
||||
|
||||
<RegExpr String="^\: [^\n]*" attribute="Documentation" context="#stay"/>
|
||||
<RegExpr String="^\@[^\n]*" attribute="Documentation" context="#stay"/>
|
||||
|
||||
<RegExpr String="\@[a-z_][a-z0-9_]*(?![a-z0-9_])" attribute="Annotation" context="#stay"/>
|
||||
|
||||
<RegExpr String="(\:\=)|(\=\:)|\%|\\|\$|(\:\:)|(\-\>)|(<\-)|(<\>)|^" attribute="Keyword" context="#stay"/>
|
||||
|
||||
<RegExpr String="\@|\:|(\?\?)|(\!\!)|(\=\>)" attribute="Control Flow" context="#stay"/>
|
||||
|
||||
<RegExpr String="''([^\\\/]|(\\.))''" attribute="Character" context="#stay"/>
|
||||
|
||||
<RegExpr String="(\.+)|([\+\\\-\*/%\^\!\?\|&,<>=]+\.?\.?\.?)" attribute="Operator" context="#stay"/>
|
||||
|
||||
<RegExpr String="([a-z_][a-z0-9_]*\.)*(([a-z_][a-z0-9_]*)|_)(?![a-z0-9_])" attribute="Name" context="#stay"/>
|
||||
|
||||
<RegExpr String="([a-z_][a-z0-9_]*\.)*[A-Z][a-zA-Z0-9]*(?![a-zA-Z0-9])" attribute="Type" context="#stay"/>
|
||||
|
||||
<RegExpr String="'(([a-z_][a-z0-9_]*(?![a-z0-9_]))|([A-Z][a-zA-Z0-9]*)(?![a-zA-Z0-9]))" attribute="ArgumentTypeOrName" context="#stay"/>
|
||||
|
||||
<RegExpr String="([a-z_][a-z0-9_]*\.)*#[A-Z][a-zA-Z0-9]*(?![a-zA-Z0-9])" attribute="Typeclass" context="#stay"/>
|
||||
|
||||
<RegExpr String="\b[0-9]+\b" attribute="Decimal" context="#stay"/>
|
||||
<RegExpr String=""([^\\"]|(\\.))*"" attribute="String" context="#stay" />
|
||||
|
||||
<DetectChar char="[" attribute="Symbol" context="#stay"/>
|
||||
<DetectChar char="]" attribute="Symbol" context="#stay"/>
|
||||
|
||||
<DetectChar char="{" attribute="Symbol" context="#stay" beginRegion="Brace"/>
|
||||
<DetectChar char="}" attribute="Symbol" context="#stay" endRegion="Brace"/>
|
||||
|
||||
<IncludeRules context="FindComments" />
|
||||
</context>
|
||||
|
||||
<context name="FindComments" attribute="Normal Text" lineEndContext="#pop">
|
||||
<Detect2Chars attribute="Comment" context="MatchComment" char="/" char1="/" lookAhead="true"/>
|
||||
<Detect2Chars attribute="Comment" context="MatchComment" char="/" char1="*" lookAhead="true" />
|
||||
</context>
|
||||
|
||||
<context name="MatchComment" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
|
||||
<Detect2Chars attribute="Comment" context="#pop!Comment" char="/" char1="/"/>
|
||||
<Detect2Chars attribute="Comment" context="#pop!MultiLine Comment" char="/" char1="*" beginRegion="Comment"/>
|
||||
</context>
|
||||
|
||||
<context attribute="Comment" lineEndContext="#pop" name="Comment">
|
||||
<LineContinue attribute="Comment" context="#stay"/>
|
||||
<DetectSpaces />
|
||||
<IncludeRules context="##Comments" />
|
||||
<DetectIdentifier />
|
||||
</context>
|
||||
|
||||
<context attribute="Comment" lineEndContext="#stay" name="MultiLine Comment">
|
||||
<DetectSpaces />
|
||||
<Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" endRegion="Comment"/>
|
||||
<IncludeRules context="##Comments" />
|
||||
<DetectIdentifier />
|
||||
</context>
|
||||
</contexts>
|
||||
<itemDatas>
|
||||
<itemData name="Normal Text" defStyleNum="dsNormal"/>
|
||||
<itemData name="Control Flow" defStyleNum="dsControlFlow" spellChecking="false"/>
|
||||
<itemData name="Keyword" defStyleNum="dsKeyword" spellChecking="false"/>
|
||||
<itemData name="Type" defStyleNum="dsDataType" spellChecking="false"/>
|
||||
<itemData name="ArgumentTypeOrName" defStyleNum="dsBuiltIn" spellChecking="false"/>
|
||||
<itemData name="Constructor" defStyleNum="dsConstant" spellChecking="false"/>
|
||||
<itemData name="Typeclass" defStyleNum="dsAttribute" spellChecking="false"/>
|
||||
<itemData name="Name" defStyleNum="dsNormal" spellChecking="false"/>
|
||||
<itemData name="Constant" defStyleNum="dsConstant" spellChecking="false"/>
|
||||
<itemData name="Annotation" defStyleNum="dsAttribute" spellChecking="false"/>
|
||||
<itemData name="Comment" defStyleNum="dsComment"/>
|
||||
<itemData name="Documentation" defStyleNum="dsDocumentation"/>
|
||||
<itemData name="Decimal" defStyleNum="dsDecVal"/>
|
||||
<itemData name="Float" defStyleNum="dsFloat"/>
|
||||
<itemData name="String" defStyleNum="dsString"/>
|
||||
<itemData name="Escape" defStyleNum="dsSpecialChar"/>
|
||||
<itemData name="Character" defStyleNum="dsChar"/>
|
||||
<itemData name="Operator" defStyleNum="dsFunction"/>
|
||||
<itemData name="Symbol" defStyleNum="dsFunction"/>
|
||||
<itemData name="Error" defStyleNum="dsError"/>
|
||||
</itemDatas>
|
||||
</highlighting>
|
||||
<general>
|
||||
<comments>
|
||||
<comment name="singleLine" start="//" />
|
||||
<comment name="multiLine" start="/*" end="*/" region="Comment" />
|
||||
</comments>
|
||||
<keywords casesensitive="1" />
|
||||
</general>
|
||||
</language>
|
||||
|
|
@ -5,41 +5,41 @@
|
|||
|
||||
namespace builders {
|
||||
|
||||
nodes::Node buildNode(parser::ParseTree::Node parser_node);
|
||||
nodes::Node build_node(parser::ParseTree::Node parser_node);
|
||||
|
||||
// --- literals
|
||||
|
||||
nodes::Literal buildFloatNumberLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_float_number_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Literal buildNumberLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_number_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Literal buildStringLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_string_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Literal buildCharLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_char_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Literal buildBoolLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Literal buildUnitLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Literal buildNullLiteral(parser::ParseTree::Node parser_node);
|
||||
nodes::Literal build_null_literal(parser::ParseTree::Node parser_node);
|
||||
|
||||
// --- identifiers
|
||||
|
||||
nodes::Identifier buildSimpleName(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier buildSimpleType(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier buildTypeclass(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_typeclass(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier buildArgumentName(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_argument_name(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier buildArgumentType(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_argument_type(parser::ParseTree::Node parser_node);
|
||||
|
||||
// Annotations are used as strings
|
||||
std::string buildAnnotation(parser::ParseTree::Node parser_node);
|
||||
std::string build_annotation(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier buildOperator(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_operator(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier buildPlaceholder(parser::ParseTree::Node parser_node);
|
||||
nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node);
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@
|
|||
#include "doc_nodes.hpp"
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace builders {
|
||||
|
||||
nodes::SymbolDocs buildSymbolDocs(
|
||||
nodes::SymbolDocs build_symbol_docs(
|
||||
parser::ParseTree::Node description_parser_node,
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes);
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes,
|
||||
const std::unordered_set<std::string> &annotations);
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
70
include/error_handling.hpp
Normal file
70
include/error_handling.hpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include "basic_nodes.hpp"
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace error_handling {
|
||||
|
||||
inline void print_position(std::ostream &out,
|
||||
std::pair<size_t, size_t> start_position,
|
||||
std::pair<size_t, size_t> end_position) {
|
||||
out << '[' << start_position.first + 1 << ", " << start_position.second + 1
|
||||
<< "] - [" << end_position.first + 1 << ", " << end_position.second + 1
|
||||
<< ']';
|
||||
}
|
||||
|
||||
inline void handle_general_error(const std::string &message) {
|
||||
std::cerr << "\x1b[1;31mGeneral Error:\x1b[0m " << message << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void
|
||||
handle_internal_error(const std::string &message, const std::string &place,
|
||||
std::optional<nodes::Node> node = std::nullopt) {
|
||||
std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at "
|
||||
<< place;
|
||||
if (node.has_value()) {
|
||||
std::cerr << ", at ";
|
||||
print_position(std::cerr, node.value().get_start_position(),
|
||||
node.value().get_end_position());
|
||||
}
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void handle_parsing_error(const std::string &message,
|
||||
parser::ParseTree::Node parse_node) {
|
||||
std::cerr << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at ";
|
||||
print_position(std::cerr, parse_node.get_start_point(),
|
||||
parse_node.get_end_point());
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void handle_typecheck_error(const std::string &message,
|
||||
nodes::Node node) {
|
||||
std::cerr << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at ";
|
||||
print_position(std::cerr, node.get_start_position(), node.get_end_position());
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void handle_runtime_error(const std::string &message, nodes::Node node) {
|
||||
std::cerr << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at ";
|
||||
print_position(std::cerr, node.get_start_position(), node.get_end_position());
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void handle_names_error(const std::string &message, nodes::Node node) {
|
||||
std::cerr << "\x1b[1;31mNames Error:\x1b[0m " << message << " at ";
|
||||
print_position(std::cerr, node.get_start_position(), node.get_end_position());
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
template <typename T> inline void debug_print(const T &value) {
|
||||
std::cerr << "\x1b[1;33mDebug:\x1b[0m " << value << '\n';
|
||||
}
|
||||
|
||||
} // namespace error_handling
|
||||
|
|
@ -1,3 +1,77 @@
|
|||
#pragma once
|
||||
|
||||
namespace builders {} // namespace builders
|
||||
#include "expression_nodes.hpp"
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
|
||||
namespace builders {
|
||||
|
||||
// --- flow control
|
||||
|
||||
nodes::ExpressionProxy
|
||||
build_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::Match build_match(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::Condition build_condition(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::Loop build_loop(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
// --- operators
|
||||
|
||||
nodes::NameExpression
|
||||
build_comma_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::NameExpression
|
||||
build_operator_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
// --- continers
|
||||
|
||||
nodes::Container build_block(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage);
|
||||
|
||||
nodes::Container build_array(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
// --- modifiers
|
||||
|
||||
nodes::Return build_return(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::NameDefinition build_name_definition(parser::ParseTree::Node parse_node);
|
||||
|
||||
nodes::Access build_array_access(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::Access build_tuple_access(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::LoopControl build_loop_control(parser::ParseTree::Node parse_node);
|
||||
|
||||
nodes::ModifierExpression
|
||||
build_reference_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::ModifierExpression
|
||||
build_suffix_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
// --- other
|
||||
|
||||
nodes::NameExpression
|
||||
build_name_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::Constructor
|
||||
build_constructor(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
nodes::Lambda build_lambda(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage& expression_storage);
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -52,17 +52,23 @@ proxy_to_expr_optional(const std::optional<nodes::ExpressionProxy> &proxy) {
|
|||
} // namespace utils
|
||||
|
||||
// --- flow control
|
||||
|
||||
class Match : public Node {
|
||||
public:
|
||||
class Case : public Node {
|
||||
public:
|
||||
Case(Node node, bool match_left_with_right, ExpressionProxy value,
|
||||
enum CaseType {
|
||||
PATTERN_VALUE,
|
||||
VALUE_PATTERN,
|
||||
};
|
||||
|
||||
Case(Node node, CaseType case_type, ExpressionProxy value,
|
||||
std::optional<ExpressionProxy> condition = std::nullopt,
|
||||
std::optional<ExpressionProxy> expression = std::nullopt)
|
||||
: Node(node), match_left_with_right_(match_left_with_right),
|
||||
value_(value), condition_(condition), expression_(expression) {}
|
||||
: Node(node), case_type_(case_type), value_(value),
|
||||
condition_(condition), expression_(expression) {}
|
||||
|
||||
bool match_left_with_right() const { return match_left_with_right_; }
|
||||
CaseType case_type() const { return case_type_; }
|
||||
|
||||
Expression *get_value() { return value_.get(); }
|
||||
|
||||
|
|
@ -85,7 +91,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool match_left_with_right_;
|
||||
CaseType case_type_;
|
||||
ExpressionProxy value_;
|
||||
std::optional<ExpressionProxy> condition_;
|
||||
std::optional<ExpressionProxy> expression_;
|
||||
|
|
@ -212,6 +218,7 @@ private:
|
|||
};
|
||||
|
||||
// --- containers
|
||||
|
||||
class Container : public Node {
|
||||
public:
|
||||
enum ContainerType {
|
||||
|
|
@ -244,6 +251,7 @@ private:
|
|||
};
|
||||
|
||||
// --- modifiers
|
||||
|
||||
class Return : public Node {
|
||||
public:
|
||||
enum ReturnType {
|
||||
|
|
@ -337,10 +345,11 @@ private:
|
|||
class ModifierExpression : public Node {
|
||||
public:
|
||||
enum Modifier {
|
||||
REFERENCE, // <> x
|
||||
MOVE, // <- x
|
||||
IF_VALUE, // x?
|
||||
VALUE_OR_PANIC, // x!
|
||||
OUT, // -> x
|
||||
IN, // <- x
|
||||
REF, // <> x
|
||||
OR_FALSE, // x?
|
||||
OR_PANIC, // x!
|
||||
};
|
||||
|
||||
ModifierExpression(Node node, Modifier modifier, ExpressionProxy expression)
|
||||
|
|
@ -359,11 +368,16 @@ private:
|
|||
};
|
||||
|
||||
// --- other
|
||||
|
||||
class NameExpression : public Node {
|
||||
public:
|
||||
template <typename T>
|
||||
NameExpression(Node node, T &&name)
|
||||
: Node(node), name_(std::forward<T>(name)) {}
|
||||
|
||||
template <typename T, typename U, typename V>
|
||||
NameExpression(Node node, T &&name, U &&arguments = {},
|
||||
V &&prefix = std::nullopt, bool is_point_call = false)
|
||||
NameExpression(Node node, T &&name, U &&arguments, V &&prefix,
|
||||
bool is_point_call = false)
|
||||
: Node(node), name_(std::forward<T>(name)),
|
||||
arguments_(std::forward<U>(arguments)),
|
||||
prefix_(std::forward<V>(prefix)), is_point_call_(is_point_call) {}
|
||||
|
|
@ -372,19 +386,16 @@ public:
|
|||
|
||||
const std::string *get_name() const { return name_.get(); }
|
||||
|
||||
std::optional<std::pair<std::string *, std::string *>> get_prefix() {
|
||||
std::optional<const Type *> get_prefix() {
|
||||
if (prefix_.has_value()) {
|
||||
return std::pair<std::string *, std::string *>{
|
||||
prefix_.value().first.get(), prefix_.value().second.get()};
|
||||
return &prefix_.value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::pair<const std::string *, const std::string *>>
|
||||
get_prefix() const {
|
||||
std::optional<const Type *> get_prefix() const {
|
||||
if (prefix_.has_value()) {
|
||||
return std::pair<const std::string *, const std::string *>{
|
||||
prefix_.value().first.get(), prefix_.value().second.get()};
|
||||
return &prefix_.value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -420,7 +431,7 @@ private:
|
|||
std::vector<std::pair<std::optional<std::string>, ExpressionProxy>>
|
||||
arguments_;
|
||||
// universal function call syntax
|
||||
std::optional<std::pair<Identifier, Identifier>> prefix_;
|
||||
std::optional<const Type> prefix_;
|
||||
// for static methods
|
||||
bool is_point_call_ = false; // x.f ... or f x ...
|
||||
};
|
||||
|
|
@ -429,7 +440,7 @@ private:
|
|||
template NameExpression::NameExpression(
|
||||
Node, Identifier &&,
|
||||
std::vector<std::pair<std::optional<std::string>, ExpressionProxy>> &&,
|
||||
std::optional<std::pair<Identifier, Identifier>> &&, bool);
|
||||
std::optional<const Type> &&, bool);
|
||||
|
||||
class Constructor : public Node {
|
||||
public:
|
||||
|
|
@ -546,7 +557,10 @@ private:
|
|||
ModifierExpression,
|
||||
|
||||
// --- other
|
||||
NameExpression, Constructor, Lambda
|
||||
NameExpression, Constructor, Lambda,
|
||||
|
||||
// --- literal
|
||||
Literal
|
||||
|
||||
>
|
||||
expression_;
|
||||
|
|
|
|||
20
include/type_builders.hpp
Normal file
20
include/type_builders.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
#include "type_nodes.hpp"
|
||||
|
||||
namespace builders {
|
||||
|
||||
// nodes::Type build_type(parser::ParseTree::Node parse_node,
|
||||
// nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeProxy build_type_proxy(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TupleType build_tuple_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::VariantType build_variant_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
} // namespace builders
|
||||
|
|
@ -32,24 +32,24 @@ std::optional<char> to_escape_symbol(char symbol) {
|
|||
|
||||
} // namespace utils
|
||||
|
||||
nodes::Node buildNode(parser::ParseTree::Node parser_node) {
|
||||
nodes::Node build_node(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Node(parser_node.get_start_point(),
|
||||
parser_node.get_end_point());
|
||||
}
|
||||
|
||||
// --- literals
|
||||
|
||||
nodes::Literal buildFloatNumberLiteral(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(buildNode(parser_node),
|
||||
nodes::Literal build_float_number_literal(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(build_node(parser_node),
|
||||
std::stod(parser_node.get_value()));
|
||||
}
|
||||
|
||||
nodes::Literal buildNumberLiteral(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(buildNode(parser_node),
|
||||
nodes::Literal build_number_literal(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(build_node(parser_node),
|
||||
std::stoll(parser_node.get_value()));
|
||||
}
|
||||
|
||||
nodes::Literal buildStringLiteral(parser::ParseTree::Node parser_node) {
|
||||
nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) {
|
||||
std::string literal = parser_node.get_value();
|
||||
|
||||
// remove " from both sides ("string")
|
||||
|
|
@ -80,10 +80,10 @@ nodes::Literal buildStringLiteral(parser::ParseTree::Node parser_node) {
|
|||
}
|
||||
literal.resize(j);
|
||||
|
||||
return nodes::Literal(buildNode(parser_node), literal);
|
||||
return nodes::Literal(build_node(parser_node), literal);
|
||||
}
|
||||
|
||||
nodes::Literal buildCharLiteral(parser::ParseTree::Node parser_node) {
|
||||
nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) {
|
||||
std::string literal = parser_node.get_value();
|
||||
|
||||
// remove '' from both sides (''x'')
|
||||
|
|
@ -105,57 +105,58 @@ nodes::Literal buildCharLiteral(parser::ParseTree::Node parser_node) {
|
|||
ch = literal.back();
|
||||
}
|
||||
|
||||
return nodes::Literal(buildNode(parser_node), ch);
|
||||
return nodes::Literal(build_node(parser_node), ch);
|
||||
}
|
||||
|
||||
nodes::Literal buildBoolLiteral(parser::ParseTree::Node parser_node) {
|
||||
nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node) {
|
||||
std::string literal = parser_node.get_value();
|
||||
|
||||
return nodes::Literal(buildNode(parser_node),
|
||||
return nodes::Literal(build_node(parser_node),
|
||||
literal == "true" ? true : false);
|
||||
}
|
||||
|
||||
nodes::Literal buildUnitLiteral(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(buildNode(parser_node), nodes::unit{});
|
||||
nodes::Literal build_Unit_literal(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(build_node(parser_node), nodes::unit{});
|
||||
}
|
||||
|
||||
nodes::Literal buildNullLiteral(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(buildNode(parser_node), nodes::null{});
|
||||
nodes::Literal build_null_literal(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(build_node(parser_node), nodes::null{});
|
||||
}
|
||||
|
||||
// --- identifiers
|
||||
|
||||
nodes::Identifier buildSimpleName(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(buildNode(parser_node),
|
||||
nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::SIMPLE_NAME,
|
||||
parser_node.get_value());
|
||||
}
|
||||
|
||||
nodes::Identifier buildSimpleType(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(buildNode(parser_node),
|
||||
nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::SIMPLE_TYPE,
|
||||
parser_node.get_value());
|
||||
}
|
||||
|
||||
nodes::Identifier buildTypeclass(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(buildNode(parser_node), nodes::Identifier::TYPECLASS,
|
||||
nodes::Identifier build_typeclass(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::TYPECLASS,
|
||||
parser_node.get_value());
|
||||
}
|
||||
|
||||
nodes::Identifier buildArgumentName(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(buildNode(parser_node),
|
||||
nodes::Identifier build_argument_name(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::ARGUMENT_NAME,
|
||||
parser_node.get_value());
|
||||
}
|
||||
|
||||
nodes::Identifier buildArgumentType(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(buildNode(parser_node),
|
||||
nodes::Identifier build_argument_type(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::ARGUMENT_TYPE,
|
||||
parser_node.get_value());
|
||||
}
|
||||
|
||||
// Annotations are used as strings
|
||||
std::string buildAnnotation(parser::ParseTree::Node parser_node) {
|
||||
std::string build_annotation(parser::ParseTree::Node parser_node) {
|
||||
std::string identifier = parser_node.get_value();
|
||||
|
||||
// identifier.size() > 0 by parsing convention
|
||||
|
|
@ -164,7 +165,7 @@ std::string buildAnnotation(parser::ParseTree::Node parser_node) {
|
|||
return identifier;
|
||||
}
|
||||
|
||||
nodes::Identifier buildOperator(parser::ParseTree::Node parser_node) {
|
||||
nodes::Identifier build_operator(parser::ParseTree::Node parser_node) {
|
||||
std::string identifier = parser_node.get_value();
|
||||
|
||||
if (identifier.size() > 0 && identifier.front() != '.') {
|
||||
|
|
@ -174,12 +175,12 @@ nodes::Identifier buildOperator(parser::ParseTree::Node parser_node) {
|
|||
}
|
||||
}
|
||||
|
||||
return nodes::Identifier(buildNode(parser_node), nodes::Identifier::OPERATOR,
|
||||
return nodes::Identifier(build_node(parser_node), nodes::Identifier::OPERATOR,
|
||||
identifier);
|
||||
}
|
||||
|
||||
nodes::Identifier buildPlaceholder(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(buildNode(parser_node),
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::PLACEHOLDER, "_");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
#include "../include/doc_builders.hpp"
|
||||
#include "basic_builders.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace builders {
|
||||
|
||||
// TODO: check, that all annotations are exist in function definition
|
||||
nodes::SymbolDocs buildSymbolDocs(
|
||||
nodes::SymbolDocs build_symbol_docs(
|
||||
parser::ParseTree::Node description_parser_node,
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes) {
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes,
|
||||
const std::unordered_set<std::string> &annotations) {
|
||||
std::string description = description_parser_node.get_value();
|
||||
|
||||
// remove newline delimeters (": " at each new line
|
||||
|
|
@ -25,9 +27,17 @@ nodes::SymbolDocs buildSymbolDocs(
|
|||
nodes::SymbolDocs docs(description);
|
||||
|
||||
for (auto &annotation_parser_node : annotation_parser_nodes) {
|
||||
docs.add_annotation_info(
|
||||
buildAnnotation(annotation_parser_node.nth_child(0)),
|
||||
annotation_parser_node.nth_child(1));
|
||||
std::string annotation =
|
||||
build_annotation(annotation_parser_node.nth_child(0));
|
||||
|
||||
if (annotations.count(annotation) == 0) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Annotation \"" + annotation +
|
||||
"\" doesn't present in corresponding symbol",
|
||||
annotation_parser_node);
|
||||
}
|
||||
|
||||
docs.add_annotation_info(annotation, annotation_parser_node.nth_child(1));
|
||||
}
|
||||
|
||||
return docs;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,498 @@
|
|||
#include "../include/expression_builders.hpp"
|
||||
|
||||
namespace builders {} // namespace builders
|
||||
#include "basic_builders.hpp"
|
||||
#include "basic_nodes.hpp"
|
||||
#include "error_handling.hpp"
|
||||
#include "expression_nodes.hpp"
|
||||
#include "tokens.hpp"
|
||||
#include "type_nodes.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace builders {
|
||||
|
||||
nodes::ExpressionProxy
|
||||
build_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
tokens::Type type = tokens::string_to_type(parse_node.get_type());
|
||||
|
||||
switch (type) {
|
||||
// --- flow control
|
||||
case tokens::Type::MATCH:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_match(parse_node, expression_storage)));
|
||||
case tokens::Type::CONDITION:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_condition(parse_node, expression_storage)));
|
||||
case tokens::Type::LOOP:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_loop(parse_node, expression_storage)));
|
||||
// --- operators
|
||||
case tokens::Type::COMMA_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_comma_expression(parse_node, expression_storage)));
|
||||
case tokens::Type::OPERATOR_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_operator_expression(parse_node, expression_storage)));
|
||||
// --- containers
|
||||
case tokens::Type::BLOCK:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_block(parse_node, expression_storage)));
|
||||
case tokens::Type::ARRAY:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_array(parse_node, expression_storage)));
|
||||
// --- modifiers
|
||||
case tokens::Type::RETURN:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_return(parse_node, expression_storage)));
|
||||
case tokens::Type::NAME_DEFINITION:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_name_definition(parse_node)));
|
||||
case tokens::Type::ARRAY_ACCESS:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_array_access(parse_node, expression_storage)));
|
||||
case tokens::Type::TUPLE_ACCESS:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_tuple_access(parse_node, expression_storage)));
|
||||
case tokens::Type::LOOP_CONTROL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_loop_control(parse_node)));
|
||||
case tokens::Type::REFERENCE_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_reference_expression(parse_node, expression_storage)));
|
||||
case tokens::Type::SUFFIX_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_suffix_expression(parse_node, expression_storage)));
|
||||
// --- other
|
||||
case tokens::Type::NAME_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_name_expression(parse_node, expression_storage)));
|
||||
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(nodes::NameExpression(
|
||||
build_node(parse_node), build_argument_name(parse_node))));
|
||||
case tokens::Type::SIMPLE_NAME_IDENTIFIER:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(nodes::NameExpression(
|
||||
build_node(parse_node), build_simple_name(parse_node))));
|
||||
case tokens::Type::CONSTRUCTOR:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_constructor(parse_node, expression_storage)));
|
||||
case tokens::Type::LAMBDA:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_lambda(parse_node, expression_storage)));
|
||||
// --- literals
|
||||
case tokens::Type::FLOAT_NUMBER_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_float_number_literal(parse_node)));
|
||||
case tokens::Type::NUMBER_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_number_literal(parse_node)));
|
||||
case tokens::Type::STRING_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_string_literal(parse_node)));
|
||||
case tokens::Type::CHAR_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_char_literal(parse_node)));
|
||||
case tokens::Type::BOOL_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_bool_literal(parse_node)));
|
||||
case tokens::Type::UNIT_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_unit_literal(parse_node)));
|
||||
case tokens::Type::NULL_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_null_literal(parse_node)));
|
||||
default:
|
||||
error_handling::handle_parsing_error("Unexprected expression node type",
|
||||
parse_node);
|
||||
}
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
// --- flow control
|
||||
|
||||
// (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)?
|
||||
nodes::Match::Case build_case(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::string case_type = parse_node.nth_child(0).get_value();
|
||||
|
||||
std::optional<parser::ParseTree::Node> condition_node;
|
||||
std::optional<parser::ParseTree::Node> expression_node;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(1);
|
||||
|
||||
if (!current_node.is_null()) {
|
||||
if (parse_node.child_by_field_name("condition").is_null()) {
|
||||
expression_node = current_node;
|
||||
} else {
|
||||
condition_node = current_node;
|
||||
current_node = current_node.next_named_sibling();
|
||||
if (!current_node.is_null()) {
|
||||
expression_node = current_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes::Match::Case(
|
||||
build_node(parse_node),
|
||||
case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE
|
||||
: nodes::Match::Case::VALUE_PATTERN,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage),
|
||||
condition_node.has_value()
|
||||
? build_expression(condition_node.value(), expression_storage)
|
||||
: std::optional<nodes::ExpressionProxy>(),
|
||||
expression_node.has_value()
|
||||
? build_expression(expression_node.value(), expression_storage)
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
}
|
||||
|
||||
// expression case+
|
||||
nodes::Match build_match(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::vector<nodes::Match::Case> cases;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(1);
|
||||
while (!current_node.is_null()) {
|
||||
cases.push_back(build_case(current_node, expression_storage));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Match(
|
||||
build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage),
|
||||
std::move(cases));
|
||||
}
|
||||
|
||||
// ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_
|
||||
// expression)* (('!!=>', 'else') expression)?
|
||||
nodes::Condition build_condition(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
size_t named_child_count = parse_node.named_child_count();
|
||||
|
||||
std::vector<std::pair<nodes::ExpressionProxy, nodes::ExpressionProxy>> cases;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(0);
|
||||
auto next_node = current_node.next_named_sibling();
|
||||
|
||||
while (!current_node.is_null() && !next_node.is_null()) {
|
||||
cases.push_back({build_expression(current_node, expression_storage),
|
||||
build_expression(next_node, expression_storage)});
|
||||
current_node = next_node.next_named_sibling();
|
||||
if (current_node.is_null()) {
|
||||
break;
|
||||
}
|
||||
next_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Condition(
|
||||
build_node(parse_node), std::move(cases),
|
||||
named_child_count % 2 == 1
|
||||
? build_expression(parse_node.nth_named_child(named_child_count - 1),
|
||||
expression_storage)
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
}
|
||||
|
||||
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression
|
||||
nodes::Loop build_loop(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
size_t named_child_count = parse_node.named_child_count();
|
||||
|
||||
if (named_child_count == 1) { // body
|
||||
return nodes::Loop(
|
||||
build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage));
|
||||
} else if (named_child_count == 2) { // condition, body
|
||||
return nodes::Loop(
|
||||
build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage),
|
||||
build_expression(parse_node.nth_named_child(1), expression_storage));
|
||||
} else if (named_child_count == 3) { // variable, interval, body
|
||||
return nodes::Loop(
|
||||
build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage),
|
||||
build_expression(parse_node.nth_named_child(1), expression_storage),
|
||||
build_expression(parse_node.nth_named_child(2), expression_storage));
|
||||
} else {
|
||||
error_handling::handle_parsing_error(
|
||||
"Unexprected named expression amount in loop", parse_node);
|
||||
}
|
||||
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
// --- operators
|
||||
|
||||
// expression ',' expression
|
||||
nodes::NameExpression
|
||||
build_comma_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
||||
arguments.emplace_back(
|
||||
std::nullopt,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage));
|
||||
|
||||
arguments.emplace_back(
|
||||
std::nullopt,
|
||||
build_expression(parse_node.nth_named_child(1), expression_storage));
|
||||
|
||||
return nodes::NameExpression(
|
||||
build_node(parse_node),
|
||||
nodes::Identifier(
|
||||
build_node(parse_node), // can't find more precise location'
|
||||
nodes::Identifier::SIMPLE_NAME, ","),
|
||||
std::move(arguments), std::nullopt, false);
|
||||
}
|
||||
|
||||
// expression operator expression
|
||||
nodes::NameExpression
|
||||
build_operator_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
auto name_node = parse_node.child_by_field_name("name");
|
||||
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
||||
arguments.emplace_back(
|
||||
std::nullopt,
|
||||
build_expression(name_node.previous_named_sibling(), expression_storage));
|
||||
|
||||
arguments.emplace_back(
|
||||
std::nullopt,
|
||||
build_expression(name_node.next_named_sibling(), expression_storage));
|
||||
|
||||
return nodes::NameExpression(build_node(parse_node),
|
||||
build_operator(name_node), std::move(arguments),
|
||||
std::nullopt, false);
|
||||
}
|
||||
|
||||
// --- continers
|
||||
|
||||
nodes::Container
|
||||
build_container(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::Container::ContainerType container_type) {
|
||||
std::vector<nodes::ExpressionProxy> expressions;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(0).next_named_sibling();
|
||||
|
||||
while (!current_node.is_null()) {
|
||||
expressions.push_back(build_expression(current_node, expression_storage));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Container(build_node(parse_node), container_type,
|
||||
std::move(expressions));
|
||||
}
|
||||
|
||||
// '{' (expression ';')* '}'
|
||||
nodes::Container build_block(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
return build_container(parse_node, expression_storage,
|
||||
nodes::Container::BLOCK);
|
||||
}
|
||||
|
||||
// '[[' expression+ ']]'
|
||||
nodes::Container build_array(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
return build_container(parse_node, expression_storage,
|
||||
nodes::Container::ARRAY);
|
||||
}
|
||||
|
||||
// --- modifiers
|
||||
|
||||
// ('return' | 'bring') expression
|
||||
nodes::Return build_return(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::string modifier = parse_node.nth_child(0).get_value();
|
||||
|
||||
return nodes::Return(
|
||||
build_node(parse_node),
|
||||
modifier == "return" ? nodes::Return::RETURN : nodes::Return::BRING,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage));
|
||||
}
|
||||
|
||||
// _var_let_ (simple_name_identifier | placeholder)
|
||||
nodes::NameDefinition
|
||||
build_name_definition(parser::ParseTree::Node parse_node) {
|
||||
std::string modifier = parse_node.nth_child(0).get_value();
|
||||
|
||||
auto name_node = parse_node.nth_named_child(0);
|
||||
|
||||
return nodes::NameDefinition(build_node(parse_node),
|
||||
(modifier == "%" || modifier == "let")
|
||||
? nodes::NameDefinition::LET
|
||||
: nodes::NameDefinition::VAR,
|
||||
tokens::string_to_type(name_node.get_type()) ==
|
||||
tokens::Type::SIMPLE_NAME_IDENTIFIER
|
||||
? build_simple_name(name_node)
|
||||
: build_placeholder(name_node));
|
||||
} // IN PROGRESS
|
||||
|
||||
// expression '[' expression ']'
|
||||
nodes::Access build_array_access(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
return nodes::Access(
|
||||
build_node(parse_node), nodes::Access::ARRAY,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage),
|
||||
build_expression(parse_node.nth_named_child(1), expression_storage));
|
||||
}
|
||||
|
||||
// expression '.' number_literal
|
||||
nodes::Access build_tuple_access(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
return nodes::Access(
|
||||
build_node(parse_node), nodes::Access::TUPLE,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage),
|
||||
expression_storage.add_expression(nodes::Expression(
|
||||
build_number_literal(parse_node.nth_named_child(1)))));
|
||||
}
|
||||
|
||||
// 'break' | 'continue'
|
||||
nodes::LoopControl build_loop_control(parser::ParseTree::Node parse_node) {
|
||||
return nodes::LoopControl(build_node(parse_node),
|
||||
parse_node.get_value() == "break"
|
||||
? nodes::LoopControl::BREAK
|
||||
: nodes::LoopControl::CONTINUE);
|
||||
}
|
||||
|
||||
nodes::ModifierExpression::Modifier
|
||||
string_to_modifier(const std::string &modifier) {
|
||||
if (modifier == "?") {
|
||||
return nodes::ModifierExpression::OR_FALSE;
|
||||
} else if (modifier == "!") {
|
||||
return nodes::ModifierExpression::OR_PANIC;
|
||||
} else if (modifier == "->" || modifier == "out") {
|
||||
return nodes::ModifierExpression::OUT;
|
||||
} else if (modifier == "<-" || modifier == "in") {
|
||||
return nodes::ModifierExpression::IN;
|
||||
} else if (modifier == "<>" || modifier == "ref") {
|
||||
return nodes::ModifierExpression::REF;
|
||||
} else {
|
||||
error_handling::handle_internal_error("Unrecognized modifier",
|
||||
"builders::modifier_by_string");
|
||||
}
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nodes::ModifierExpression
|
||||
build_modifier_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
size_t modifier_position) {
|
||||
std::string modifier = parse_node.nth_child(modifier_position).get_value();
|
||||
|
||||
return nodes::ModifierExpression(
|
||||
build_node(parse_node), string_to_modifier(modifier),
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage));
|
||||
}
|
||||
|
||||
// _reference_ expression
|
||||
nodes::ModifierExpression
|
||||
build_reference_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
return build_modifier_expression(parse_node, expression_storage, 0);
|
||||
}
|
||||
|
||||
// expression ('?' | '!')
|
||||
nodes::ModifierExpression
|
||||
build_suffix_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
return build_modifier_expression(parse_node, expression_storage,
|
||||
parse_node.child_count() - 1);
|
||||
}
|
||||
|
||||
// --- other
|
||||
|
||||
void build_arguments_until_end(
|
||||
parser::ParseTree::Node first_parse_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
&arguments) {
|
||||
|
||||
auto current_node = first_parse_node;
|
||||
|
||||
std::optional<std::string> last_annotation;
|
||||
while (!current_node.is_null()) {
|
||||
if (tokens::string_to_type(current_node.get_type()) ==
|
||||
tokens::Type::ANNOTATION_IDENTIFIER) {
|
||||
last_annotation = build_annotation(current_node);
|
||||
} else {
|
||||
arguments.emplace_back(
|
||||
std::move(last_annotation),
|
||||
build_expression(current_node, expression_storage));
|
||||
last_annotation = std::nullopt;
|
||||
}
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
}
|
||||
|
||||
// (type '.' simple_name | expression '.' simple_name | name | '(' operator
|
||||
// ')') (annotation? expression)*
|
||||
nodes::NameExpression
|
||||
build_name_expression(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
||||
std::optional<nodes::Type> prefix;
|
||||
|
||||
bool is_point_call = false;
|
||||
|
||||
auto name_node = parse_node.child_by_field_name("name");
|
||||
|
||||
auto type_node = name_node.previous_named_sibling();
|
||||
|
||||
if (!type_node.is_null()) {
|
||||
if (tokens::string_to_type(type_node.get_type()) == tokens::Type::TYPE) {
|
||||
prefix = build_type(type_node);
|
||||
} else {
|
||||
is_point_call = true;
|
||||
arguments.emplace_back(std::nullopt,
|
||||
build_expression(type_node, expression_storage));
|
||||
}
|
||||
}
|
||||
|
||||
build_arguments_until_end(name_node.next_named_sibling(), expression_storage,
|
||||
arguments);
|
||||
|
||||
return nodes::NameExpression(
|
||||
build_node(parse_node), build_simple_name(name_node),
|
||||
std::move(arguments), std::move(prefix), is_point_call);
|
||||
} // IN PROGRESS
|
||||
|
||||
// type (annotation? expression)*
|
||||
nodes::Constructor
|
||||
build_constructor(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
||||
build_arguments_until_end(
|
||||
parse_node.child_by_field_name("type").next_named_sibling(),
|
||||
expression_storage, arguments);
|
||||
|
||||
return nodes::Constructor(build_node(parse_node),
|
||||
build_type(parse_node.child_by_field_name("type")),
|
||||
std::move(arguments));
|
||||
}
|
||||
|
||||
// '\\' argument_name* _do_ expression
|
||||
nodes::Lambda build_lambda(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage) {
|
||||
std::vector<nodes::Identifier> arguments;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(0);
|
||||
while (tokens::string_to_type(current_node.get_type()) ==
|
||||
tokens::Type::ARGUMENT_NAME_IDENTIFIER) {
|
||||
arguments.emplace_back(build_argument_name(parse_node));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
return nodes::Lambda(build_node(parse_node), std::move(arguments),
|
||||
build_expression(current_node, expression_storage));
|
||||
}
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
17
src/type_builders.cpp
Normal file
17
src/type_builders.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include "../include/type_builders.hpp"
|
||||
|
||||
namespace builders {
|
||||
|
||||
// nodes::Type build_type(parser::ParseTree::Node parse_node,
|
||||
// nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeProxy build_type_proxy(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TupleType build_tuple_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::VariantType build_variant_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
} // namespace builders
|
||||
Loading…
Add table
Add a link
Reference in a new issue