mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
basic printers, type printers, some fixes, part of expression printers
This commit is contained in:
parent
3914ff7d8b
commit
3669084f55
14 changed files with 795 additions and 39 deletions
2
deps/tree-sitter-lang
vendored
2
deps/tree-sitter-lang
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit b26c0544bf0dea60a421d4672c3f2997f445b5ff
|
||||
Subproject commit 18d84f5f28da3722749477b3bfa58e1dba397bf5
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
<item>elif</item>
|
||||
<item>else</item>
|
||||
<item>for</item>
|
||||
<item>loop</item>
|
||||
<item>do</item>
|
||||
<item>break</item>
|
||||
<item>continue</item>
|
||||
|
|
@ -15,11 +14,13 @@
|
|||
<item>bring</item>
|
||||
</list>
|
||||
<list name="keywords">
|
||||
<item>import</item>
|
||||
<item>out</item>
|
||||
<item>in</item>
|
||||
<item>ref</item>
|
||||
<item>let</item>
|
||||
<item>var</item>
|
||||
<item>lambda</item>
|
||||
<item>exec</item>
|
||||
<item>test</item>
|
||||
<item>example</item>
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
namespace nodes {
|
||||
|
||||
enum class Modifier {
|
||||
OUT, // -> x
|
||||
IN, // <- x
|
||||
REF, // <> x
|
||||
OR_FALSE, // x?
|
||||
OR_PANIC, // x!
|
||||
OUT, // -> x
|
||||
IN, // <- x
|
||||
REF, // <> x
|
||||
OR_FALSE, // x?
|
||||
OR_RETURN, // x!
|
||||
NONE,
|
||||
};
|
||||
|
||||
|
|
@ -53,6 +53,16 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<double, long long, std::string, char, bool, unit, null> *
|
||||
get_any() {
|
||||
return &value_;
|
||||
}
|
||||
|
||||
const std::variant<double, long long, std::string, char, bool, unit, null> *
|
||||
get_any() const {
|
||||
return &value_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::variant<double, long long, std::string, char, bool, unit, null> value_;
|
||||
};
|
||||
|
|
|
|||
52
include/basic_printers.hpp
Normal file
52
include/basic_printers.hpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include "basic_nodes.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace printers {
|
||||
|
||||
class Printer {
|
||||
public:
|
||||
Printer(std::ostream &output, size_t tab_width,
|
||||
bool print_words_instead_of_symbols)
|
||||
: output_(output), tab_width_(tab_width),
|
||||
print_words_instead_of_symbols_(print_words_instead_of_symbols),
|
||||
current_column_(0) {}
|
||||
|
||||
template <typename T> void print(const T &value) { output_ << value; }
|
||||
|
||||
void new_line() {
|
||||
print('\n');
|
||||
print_spaces(current_column_ * tab_width_);
|
||||
}
|
||||
|
||||
void indent() { ++current_column_; }
|
||||
|
||||
void deindent() { --current_column_; }
|
||||
|
||||
void tab() { print_spaces(tab_width_); }
|
||||
|
||||
void space() { print_spaces(1); }
|
||||
|
||||
bool print_words_instead_of_symbols() {
|
||||
return print_words_instead_of_symbols_;
|
||||
}
|
||||
|
||||
private:
|
||||
void print_spaces(size_t n) { print(std::string(n, ' ')); }
|
||||
|
||||
private:
|
||||
std::ostream &output_;
|
||||
size_t tab_width_ = 2;
|
||||
bool print_words_instead_of_symbols_ = false;
|
||||
|
||||
size_t current_column_ = 0;
|
||||
};
|
||||
|
||||
void print_literal(const nodes::Literal &literal, Printer &printer);
|
||||
|
||||
void print_identifier(const nodes::Identifier &identifier, Printer &printer);
|
||||
|
||||
void print_annotation(const std::string &annotation, Printer &printer);
|
||||
|
||||
} // namespace printers
|
||||
|
|
@ -177,7 +177,7 @@ public:
|
|||
: Node(node), type_(FOR), expression_(expression), variable_(variable),
|
||||
interval_(interval) {}
|
||||
|
||||
LoopType get_type() { return type_; }
|
||||
LoopType get_type() const { return type_; }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ public:
|
|||
const std::vector<ExpressionProxy> &expressions)
|
||||
: Node(node), type_(type), expressions_(expressions) {}
|
||||
|
||||
ContainerType get_type() { return type_; }
|
||||
ContainerType get_type() const { return type_; }
|
||||
|
||||
size_t expressions_size() const { return expressions_.size(); }
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ public:
|
|||
Return(Node node, ReturnType type, ExpressionProxy expression)
|
||||
: Node(node), type_(type), expression_(expression) {}
|
||||
|
||||
ReturnType get_type() { return type_; }
|
||||
ReturnType get_type() const { return type_; }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
|
||||
|
|
@ -287,11 +287,11 @@ public:
|
|||
NameDefinition(Node node, Modifier modifier, const Identifier &name)
|
||||
: Node(node), modifier_(modifier), name_(name) {}
|
||||
|
||||
Modifier get_modifier() { return modifier_; }
|
||||
Modifier get_modifier() const { return modifier_; }
|
||||
|
||||
std::string *get_name() { return name_.get(); }
|
||||
Identifier *get_name() { return &name_; }
|
||||
|
||||
const std::string *get_name() const { return name_.get(); }
|
||||
const Identifier *get_name() const { return &name_; }
|
||||
|
||||
private:
|
||||
Modifier modifier_;
|
||||
|
|
@ -310,7 +310,7 @@ public:
|
|||
ExpressionProxy index)
|
||||
: Node(node), type_(type), value_(value), index_(index) {}
|
||||
|
||||
AccessType get_type() { return type_; }
|
||||
AccessType get_type() const { return type_; }
|
||||
|
||||
Expression *get_value() { return value_.get(); }
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ public:
|
|||
|
||||
LoopControl(Node node, LoopControlType type) : Node(node), type_(type) {}
|
||||
|
||||
LoopControlType get_type() { return type_; }
|
||||
LoopControlType get_type() const { return type_; }
|
||||
|
||||
private:
|
||||
LoopControlType type_;
|
||||
|
|
@ -347,7 +347,7 @@ public:
|
|||
ModifierExpression(Node node, Modifier modifier, ExpressionProxy expression)
|
||||
: Node(node), modifier_(modifier), expression_(expression) {}
|
||||
|
||||
Modifier get_modifier() { return modifier_; }
|
||||
Modifier get_modifier() const { return modifier_; }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
|
||||
|
|
@ -372,24 +372,26 @@ public:
|
|||
Node node, Identifier &&name,
|
||||
std::vector<std::pair<std::optional<std::string>, ExpressionProxy>>
|
||||
&&arguments,
|
||||
std::optional<TypeProxy> &&prefix, bool is_point_call = false)
|
||||
std::optional<TypeProxy> &&prefix, bool is_point_call = false,
|
||||
bool is_operator_call = false)
|
||||
: Node(node), name_(std::move(name)), arguments_(std::move(arguments)),
|
||||
prefix_(std::move(prefix)), is_point_call_(is_point_call) {}
|
||||
prefix_(std::move(prefix)), is_point_call_(is_point_call),
|
||||
is_operator_call_(is_operator_call) {}
|
||||
|
||||
std::string *get_name() { return name_.get(); }
|
||||
Identifier *get_name() { return &name_; }
|
||||
|
||||
const std::string *get_name() const { return name_.get(); }
|
||||
const Identifier *get_name() const { return &name_; }
|
||||
|
||||
std::optional<TypeProxy> get_prefix() {
|
||||
std::optional<Type *> get_prefix() {
|
||||
if (prefix_.has_value()) {
|
||||
return prefix_.value();
|
||||
return prefix_.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const TypeProxy> get_prefix() const {
|
||||
std::optional<const Type *> get_prefix() const {
|
||||
if (prefix_.has_value()) {
|
||||
return prefix_.value();
|
||||
return prefix_.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -418,7 +420,9 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool is_point_call() { return is_point_call_; }
|
||||
bool is_point_call() const { return is_point_call_; }
|
||||
|
||||
bool is_operator_call() const { return is_operator_call_; }
|
||||
|
||||
private:
|
||||
Identifier name_;
|
||||
|
|
@ -427,7 +431,8 @@ private:
|
|||
arguments_;
|
||||
std::optional<TypeProxy> prefix_;
|
||||
// for static methods
|
||||
bool is_point_call_ = false; // x.f ... or f x ...
|
||||
bool is_point_call_ = false; // x.f ... or f x ...
|
||||
bool is_operator_call_ = false; // ... operator ...
|
||||
};
|
||||
|
||||
class Constructor : public Node {
|
||||
|
|
@ -506,7 +511,8 @@ private:
|
|||
class Expression {
|
||||
public:
|
||||
template <typename T>
|
||||
Expression(T &&expression) : expression_(std::forward<T>(expression)) {}
|
||||
Expression(T &&expression, bool is_scoped)
|
||||
: expression_(std::forward<T>(expression)), is_scoped_(is_scoped) {}
|
||||
|
||||
template <typename T> std::optional<T *> get() {
|
||||
if (std::holds_alternative<T>(expression_)) {
|
||||
|
|
@ -522,6 +528,8 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool is_scoped() const { return is_scoped_; }
|
||||
|
||||
private:
|
||||
std::variant<
|
||||
|
||||
|
|
@ -552,6 +560,8 @@ private:
|
|||
|
||||
>
|
||||
expression_;
|
||||
|
||||
bool is_scoped_ = false;
|
||||
};
|
||||
|
||||
class ExpressionStorage {
|
||||
|
|
|
|||
49
include/expression_printers.hpp
Normal file
49
include/expression_printers.hpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include "basic_printers.hpp"
|
||||
#include "expression_nodes.hpp"
|
||||
namespace printers {
|
||||
|
||||
void print_expression(const nodes::Expression &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
// --- flow control
|
||||
|
||||
void print_match(const nodes::Match &expression, printers::Printer &printer);
|
||||
|
||||
void print_condition(const nodes::Condition &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
void print_loop(const nodes::Loop &expression, printers::Printer &printer);
|
||||
|
||||
// --- containers
|
||||
|
||||
void print_container(const nodes::Container &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
// --- modifiers
|
||||
|
||||
void print_return(const nodes::Return &expression, printers::Printer &printer);
|
||||
|
||||
void print_name_definition(const nodes::NameDefinition &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
void print_access(const nodes::Access &expression, printers::Printer &printer);
|
||||
|
||||
void print_loop_control(const nodes::LoopControl &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
void print_modifier_expression(const nodes::ModifierExpression &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
// --- other
|
||||
|
||||
void print_name_expression(const nodes::NameExpression &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
void print_constructor(const nodes::Constructor &expression,
|
||||
printers::Printer &printer);
|
||||
|
||||
void print_lambda(const nodes::Lambda &expression, printers::Printer &printer);
|
||||
|
||||
} // namespace printers
|
||||
|
|
@ -31,6 +31,7 @@ private:
|
|||
size_t id_;
|
||||
};
|
||||
|
||||
// can't have both optional and result modifiers ??
|
||||
class Type : public Node {
|
||||
public:
|
||||
Type(Node node, Identifier &&identifier, bool is_on_heap = false,
|
||||
|
|
@ -61,7 +62,7 @@ public:
|
|||
|
||||
const std::string *get_name() const { return name_.get(); }
|
||||
|
||||
size_t get_parametrs_size() { return parameters_.size(); }
|
||||
size_t get_parametrs_size() const { return parameters_.size(); }
|
||||
|
||||
Type *get_parameter(size_t id) { return parameters_.at(id).get(); }
|
||||
|
||||
|
|
@ -69,11 +70,11 @@ public:
|
|||
return parameters_.at(id).get();
|
||||
}
|
||||
|
||||
bool is_on_heap() { return is_on_heap_; }
|
||||
bool is_on_heap() const { return is_on_heap_; }
|
||||
|
||||
bool is_optional() { return is_optional_; }
|
||||
bool is_optional() const { return is_optional_; }
|
||||
|
||||
bool is_result() { return is_result_; }
|
||||
bool is_result() const { return is_result_; }
|
||||
|
||||
private:
|
||||
Identifier name_;
|
||||
|
|
@ -113,16 +114,32 @@ public:
|
|||
const std::vector<std::pair<std::optional<std::string>, TypeProxy>>
|
||||
&fields)
|
||||
: Node(node) {
|
||||
annotations_.reserve(fields.size());
|
||||
fields_.reserve(fields.size());
|
||||
for (auto &field : fields) {
|
||||
if (field.first.has_value()) {
|
||||
annotation_fields_[field.first.value()] = fields_.size();
|
||||
}
|
||||
annotations_.push_back(field.first);
|
||||
fields_.push_back(field.second);
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() { return fields_.size(); }
|
||||
size_t size() const { return fields_.size(); }
|
||||
|
||||
std::optional<std::string *> get_annotation(size_t id) {
|
||||
if (annotations_.at(id).has_value()) {
|
||||
return &annotations_[id].value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const std::string *> get_annotation(size_t id) const {
|
||||
if (annotations_.at(id).has_value()) {
|
||||
return &annotations_[id].value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Type *get(size_t id) { return fields_.at(id).get(); }
|
||||
|
||||
|
|
@ -150,6 +167,7 @@ public:
|
|||
private:
|
||||
std::unordered_map<std::string, size_t> annotation_fields_;
|
||||
std::vector<TypeProxy> fields_;
|
||||
std::vector<std::optional<std::string>> annotations_;
|
||||
};
|
||||
|
||||
class VariantType : public Node {
|
||||
|
|
@ -160,7 +178,7 @@ public:
|
|||
VariantType(Node node, const std::vector<TupleType> &constructors_)
|
||||
: Node(node), constructors_(constructors_) {}
|
||||
|
||||
size_t size() { return constructors_.size(); }
|
||||
size_t size() const { return constructors_.size(); }
|
||||
|
||||
TupleType *get(size_t id) { return &constructors_.at(id); }
|
||||
|
||||
|
|
|
|||
15
include/type_printers.hpp
Normal file
15
include/type_printers.hpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "basic_printers.hpp"
|
||||
#include "type_nodes.hpp"
|
||||
|
||||
namespace printers {
|
||||
|
||||
void print_type(const nodes::Type &type, printers::Printer &printer);
|
||||
|
||||
void print_tuple_type(const nodes::TupleType &type, printers::Printer &printer);
|
||||
|
||||
void print_variant_type(const nodes::VariantType &type,
|
||||
printers::Printer &printer);
|
||||
|
||||
} // namespace printers
|
||||
|
|
@ -8,8 +8,8 @@
|
|||
namespace builders {
|
||||
|
||||
namespace utils {
|
||||
std::optional<char> to_escape_symbol(char symbol) {
|
||||
switch (symbol) {
|
||||
std::optional<char> to_escape_symbol(char ch) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
return '\a';
|
||||
case 'b':
|
||||
|
|
@ -41,7 +41,7 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
|
|||
if (modifier == "?") {
|
||||
return nodes::Modifier::OR_FALSE;
|
||||
} else if (modifier == "!") {
|
||||
return nodes::Modifier::OR_PANIC;
|
||||
return nodes::Modifier::OR_RETURN;
|
||||
} else if (modifier == "->" || modifier == "out") {
|
||||
return nodes::Modifier::OUT;
|
||||
} else if (modifier == "<-" || modifier == "in") {
|
||||
|
|
|
|||
83
src/basic_printers.cpp
Normal file
83
src/basic_printers.cpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#include "basic_printers.hpp"
|
||||
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace printers {
|
||||
|
||||
namespace utils {
|
||||
std::string to_printable_symbol(char ch) {
|
||||
switch (ch) {
|
||||
case '\a':
|
||||
return "\\a";
|
||||
case '\b':
|
||||
return "\\b";
|
||||
case '\e':
|
||||
return "\\e";
|
||||
case '\f':
|
||||
return "\\f";
|
||||
case '\n':
|
||||
return "\\n";
|
||||
case '\r':
|
||||
return "\\r";
|
||||
case '\t':
|
||||
return "\\t";
|
||||
case '\v':
|
||||
return "\\v";
|
||||
// case ' ':
|
||||
// return "\\s";
|
||||
default:
|
||||
return std::string(1, ch);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
void print_literal(const nodes::Literal &literal, Printer &printer) {
|
||||
switch (literal.get_any()->index()) {
|
||||
case 0: // double
|
||||
// print in parseable form ??
|
||||
printer.print(literal.get<double>().value());
|
||||
return;
|
||||
case 1: // long long
|
||||
printer.print(literal.get<long long>().value());
|
||||
return;
|
||||
case 2: // std::string
|
||||
printer.print("\"\"");
|
||||
// more efficient approach ??
|
||||
for (auto &ch : *literal.get<std::string>().value()) {
|
||||
printer.print(utils::to_printable_symbol(ch));
|
||||
}
|
||||
printer.print("\"\"");
|
||||
return;
|
||||
case 3: // char
|
||||
printer.print("\'\'");
|
||||
printer.print(utils::to_printable_symbol(*literal.get<char>().value()));
|
||||
printer.print("\'\'");
|
||||
return;
|
||||
case 4: // bool
|
||||
printer.print(literal.get<bool>().value() ? "true" : "false");
|
||||
return;
|
||||
case 5: // unit
|
||||
printer.print("()");
|
||||
return;
|
||||
case 6: // null
|
||||
printer.print("null");
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
void print_identifier(const nodes::Identifier &identifier, Printer &printer) {
|
||||
printer.print(identifier.get());
|
||||
}
|
||||
|
||||
void print_annotation(const std::string &annotation, Printer &printer) {
|
||||
printer.print('@');
|
||||
printer.print(annotation);
|
||||
}
|
||||
|
||||
} // namespace printers
|
||||
|
|
@ -258,7 +258,7 @@ build_comma_expression(parser::ParseTree::Node parser_node,
|
|||
nodes::Identifier(
|
||||
build_node(parser_node), // can't find more precise location'
|
||||
nodes::Identifier::SIMPLE_NAME, ","),
|
||||
std::move(arguments), std::nullopt, false);
|
||||
std::move(arguments), std::nullopt, false, true);
|
||||
}
|
||||
|
||||
// expression operator expression
|
||||
|
|
@ -281,7 +281,7 @@ build_operator_expression(parser::ParseTree::Node parser_node,
|
|||
|
||||
return nodes::NameExpression(build_node(parser_node),
|
||||
build_operator(name_node), std::move(arguments),
|
||||
std::nullopt, false);
|
||||
std::nullopt, false, true);
|
||||
}
|
||||
|
||||
// --- continers
|
||||
|
|
@ -475,7 +475,7 @@ build_name_expression(parser::ParseTree::Node parser_node,
|
|||
std::move(arguments),
|
||||
prefix_node.has_value() ? build_type(prefix_node.value(), type_storage)
|
||||
: std::optional<nodes::TypeProxy>(),
|
||||
is_point_call);
|
||||
is_point_call, false);
|
||||
}
|
||||
|
||||
// type (annotation? expression)*
|
||||
|
|
|
|||
225
src/expression_printers.cpp
Normal file
225
src/expression_printers.cpp
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
#include "expression_printers.hpp"
|
||||
#include "basic_nodes.hpp"
|
||||
#include "basic_printers.hpp"
|
||||
#include "expression_nodes.hpp"
|
||||
#include "type_printers.hpp"
|
||||
|
||||
namespace printers {
|
||||
|
||||
void print_expression(const nodes::Expression &expression,
|
||||
printers::Printer &printer) {} // IN PROGRESS
|
||||
|
||||
// --- flow control
|
||||
|
||||
void print_match(const nodes::Match &expression, printers::Printer &printer) {
|
||||
} // IN PROGRESS
|
||||
|
||||
void print_condition(const nodes::Condition &expression,
|
||||
printers::Printer &printer) {} // IN PROGRESS
|
||||
|
||||
void print_loop(const nodes::Loop &expression, printers::Printer &printer) {
|
||||
} // IN PROGRESS
|
||||
|
||||
// --- containers
|
||||
|
||||
void print_container(const nodes::Container &expression,
|
||||
printers::Printer &printer) {} // IN PROGRESS
|
||||
|
||||
// --- modifiers
|
||||
|
||||
void print_return(const nodes::Return &expression, printers::Printer &printer) {
|
||||
|
||||
switch (expression.get_type()) {
|
||||
case nodes::Return::RETURN:
|
||||
printer.print("return ");
|
||||
break;
|
||||
case nodes::Return::BRING:
|
||||
printer.print("bring ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
print_expression(*expression.get_expression(), printer);
|
||||
}
|
||||
|
||||
void print_name_definition(const nodes::NameDefinition &expression,
|
||||
printers::Printer &printer) {
|
||||
|
||||
if (printer.print_words_instead_of_symbols()) {
|
||||
switch (expression.get_modifier()) {
|
||||
case nodes::NameDefinition::LET:
|
||||
printer.print("let ");
|
||||
break;
|
||||
case nodes::NameDefinition::VAR:
|
||||
printer.print("var ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.get_modifier()) {
|
||||
case nodes::NameDefinition::LET:
|
||||
printer.print("% ");
|
||||
break;
|
||||
case nodes::NameDefinition::VAR:
|
||||
printer.print("$ ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_identifier(*expression.get_name(), printer);
|
||||
}
|
||||
|
||||
void print_access(const nodes::Access &expression, printers::Printer &printer) {
|
||||
print_expression(*expression.get_value(), printer);
|
||||
|
||||
switch (expression.get_type()) {
|
||||
case nodes::Access::ARRAY:
|
||||
printer.print('[');
|
||||
break;
|
||||
case nodes::Access::TUPLE:
|
||||
printer.print('.');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
print_expression(*expression.get_index(), printer);
|
||||
|
||||
switch (expression.get_type()) {
|
||||
case nodes::Access::ARRAY:
|
||||
printer.print(']');
|
||||
break;
|
||||
case nodes::Access::TUPLE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void print_loop_control(const nodes::LoopControl &expression,
|
||||
printers::Printer &printer) {
|
||||
switch (expression.get_type()) {
|
||||
case nodes::LoopControl::BREAK:
|
||||
printer.print("break");
|
||||
break;
|
||||
case nodes::LoopControl::CONTINUE:
|
||||
printer.print("continue");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void print_modifier_expression(const nodes::ModifierExpression &expression,
|
||||
printers::Printer &printer) {
|
||||
|
||||
if (printer.print_words_instead_of_symbols()) {
|
||||
switch (expression.get_modifier()) {
|
||||
case nodes::Modifier::OUT:
|
||||
printer.print("out ");
|
||||
break;
|
||||
case nodes::Modifier::IN:
|
||||
printer.print("in ");
|
||||
break;
|
||||
case nodes::Modifier::REF:
|
||||
printer.print("ref ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.get_modifier()) {
|
||||
case nodes::Modifier::OUT:
|
||||
printer.print("-> ");
|
||||
break;
|
||||
case nodes::Modifier::IN:
|
||||
printer.print("<- ");
|
||||
break;
|
||||
case nodes::Modifier::REF:
|
||||
printer.print("<> ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_expression(*expression.get_expression(), printer);
|
||||
|
||||
switch (expression.get_modifier()) {
|
||||
case nodes::Modifier::OR_FALSE:
|
||||
printer.print('?');
|
||||
break;
|
||||
case nodes::Modifier::OR_RETURN:
|
||||
printer.print('!');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// --- other
|
||||
|
||||
void print_name_expression(const nodes::NameExpression &expression,
|
||||
printers::Printer &printer) {
|
||||
if (expression.is_operator_call() || expression.is_point_call()) {
|
||||
print_expression(*expression.get_argument_value(0), printer);
|
||||
if (expression.is_point_call()) {
|
||||
printer.print('.');
|
||||
} else {
|
||||
printer.space();
|
||||
}
|
||||
} else if (expression.get_prefix().has_value()) {
|
||||
print_type(*expression.get_prefix().value(), printer);
|
||||
printer.print('.');
|
||||
}
|
||||
|
||||
print_identifier(*expression.get_name(), printer);
|
||||
|
||||
for (size_t i = 0; i < expression.arguments_size(); ++i) {
|
||||
printer.space();
|
||||
|
||||
if (expression.get_argument_annotation(i).has_value()) {
|
||||
print_annotation(*expression.get_argument_annotation(i).value(), printer);
|
||||
printer.space();
|
||||
}
|
||||
print_expression(*expression.get_argument_value(i), printer);
|
||||
}
|
||||
|
||||
} // IN PROGRESS
|
||||
|
||||
void print_constructor(const nodes::Constructor &expression,
|
||||
printers::Printer &printer) {
|
||||
print_type(*expression.get_type(), printer);
|
||||
|
||||
for (size_t i = 0; i < expression.arguments_size(); ++i) {
|
||||
printer.space();
|
||||
|
||||
if (expression.get_argument_annotation(i).has_value()) {
|
||||
print_annotation(*expression.get_argument_annotation(i).value(), printer);
|
||||
printer.space();
|
||||
}
|
||||
|
||||
print_expression(*expression.get_argument_value(i), printer);
|
||||
}
|
||||
|
||||
} // IN PROGRESS
|
||||
|
||||
void print_lambda(const nodes::Lambda &expression, printers::Printer &printer) {
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ ");
|
||||
|
||||
for (size_t i = 0; i < expression.arguments_size(); ++i) {
|
||||
print_identifier(*expression.get_argument(i), printer);
|
||||
printer.space();
|
||||
}
|
||||
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "do " : "-> ");
|
||||
|
||||
print_expression(*expression.get_expression(), printer);
|
||||
|
||||
} // IN PROGRESS
|
||||
|
||||
} // namespace printers
|
||||
61
src/type_printers.cpp
Normal file
61
src/type_printers.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include "type_printers.hpp"
|
||||
#include "basic_printers.hpp"
|
||||
#include "type_nodes.hpp"
|
||||
|
||||
namespace printers {
|
||||
|
||||
void print_type(const nodes::Type &type, printers::Printer &printer) {
|
||||
if (type.is_on_heap()) {
|
||||
printer.print('^');
|
||||
}
|
||||
|
||||
printer.print(type.get_name());
|
||||
|
||||
if (type.is_optional()) {
|
||||
printer.print('?');
|
||||
}
|
||||
|
||||
if (type.is_result()) {
|
||||
printer.print('!');
|
||||
}
|
||||
|
||||
printer.print('[');
|
||||
for (size_t i = 0; i < type.get_parametrs_size(); ++i) {
|
||||
print_type(*type.get_parameter(i), printer);
|
||||
printer.space();
|
||||
}
|
||||
printer.print(']');
|
||||
}
|
||||
|
||||
void print_tuple_type(const nodes::TupleType &type,
|
||||
printers::Printer &printer) {
|
||||
for (size_t i = 0; i < type.size(); ++i) {
|
||||
if (i > 0) {
|
||||
printer.print(" & ");
|
||||
}
|
||||
auto annotation = type.get_annotation(i);
|
||||
|
||||
if (annotation.has_value()) {
|
||||
print_annotation(*annotation.value(), printer);
|
||||
}
|
||||
|
||||
print_type(*type.get(i), printer);
|
||||
}
|
||||
}
|
||||
|
||||
void print_variant_type(const nodes::VariantType &type,
|
||||
printers::Printer &printer) {
|
||||
for (size_t i = 0; i < type.size(); ++i) {
|
||||
if (type.size() > 1 || i > 0) {
|
||||
printer.print("| ");
|
||||
}
|
||||
|
||||
print_tuple_type(*type.get(i), printer);
|
||||
|
||||
if (i + 1 < type.size()) {
|
||||
printer.new_line();
|
||||
}
|
||||
}
|
||||
} // IN PROGRESS
|
||||
|
||||
} // namespace printers
|
||||
232
tests/formatting.langexp
Normal file
232
tests/formatting.langexp
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
// import
|
||||
|
||||
:: x = y : func1 func2 func3 func4 func5;
|
||||
|
||||
:: x = y :
|
||||
func1
|
||||
func2
|
||||
func3
|
||||
func4
|
||||
func5;
|
||||
|
||||
// type
|
||||
|
||||
: info
|
||||
@a annotation info
|
||||
Type = @a A;
|
||||
|
||||
Type 'A 'B 'C = @a1 'A | @b2 'B | @c2 'C;
|
||||
|
||||
Type 'A 'B 'C
|
||||
= @a1 'A | @b2 'B | @c2 'C;
|
||||
|
||||
Type
|
||||
'A
|
||||
'B
|
||||
'C
|
||||
= @a1 'A | @b2 'B | @c2 'C;
|
||||
|
||||
Type 'A 'B 'C =
|
||||
| & @a1 'A
|
||||
& @b1 'B
|
||||
& @c1 'C
|
||||
| @a2 'A & @b2 'B & @c2 'C;
|
||||
|
||||
Type
|
||||
'A
|
||||
'B
|
||||
'C
|
||||
=
|
||||
| & @a1 'A
|
||||
& @b1 'B
|
||||
& @c1 'C
|
||||
| @a2 'A & @b2 'B & @c2 'C;
|
||||
|
||||
Type {
|
||||
|
||||
func1;
|
||||
|
||||
func2;
|
||||
|
||||
func3;
|
||||
|
||||
}
|
||||
|
||||
// typeclass
|
||||
|
||||
: info
|
||||
#Typeclass;
|
||||
|
||||
#Typeclass : #A #B #C;
|
||||
|
||||
#Typeclass :
|
||||
#A
|
||||
#B
|
||||
#C;
|
||||
|
||||
// function
|
||||
|
||||
: info
|
||||
@a annotation info
|
||||
func 'a;
|
||||
|
||||
func 'a 'b 'c : A B C -> D;
|
||||
|
||||
func
|
||||
'a
|
||||
'b
|
||||
'c
|
||||
: A B C -> D;
|
||||
|
||||
func 'a 'b 'c
|
||||
: A B C -> D;
|
||||
|
||||
func
|
||||
'a
|
||||
'b
|
||||
'c
|
||||
: A B C -> D
|
||||
|
||||
func 'a 'b 'c
|
||||
:
|
||||
A
|
||||
B
|
||||
C
|
||||
-> D;
|
||||
|
||||
func
|
||||
'a
|
||||
'b
|
||||
'c
|
||||
:
|
||||
A
|
||||
B
|
||||
C
|
||||
-> D;
|
||||
|
||||
// flow control
|
||||
|
||||
func = {
|
||||
x := y => do_something
|
||||
:= z
|
||||
=> do_something;
|
||||
|
||||
@ => do_something;
|
||||
|
||||
@ a => do_something;
|
||||
|
||||
@ a
|
||||
=> do_something;
|
||||
|
||||
@ a : b => do_something;
|
||||
|
||||
@ a : b
|
||||
=> do_something;
|
||||
|
||||
}
|
||||
|
||||
// operators, containers, modifiers
|
||||
|
||||
func {
|
||||
|
||||
x + y;
|
||||
|
||||
x
|
||||
+ y;
|
||||
|
||||
{
|
||||
expr;
|
||||
expr;
|
||||
expr;
|
||||
};
|
||||
|
||||
[[ expr expr expr ]];
|
||||
|
||||
[[
|
||||
expr
|
||||
expr
|
||||
expr
|
||||
]];
|
||||
|
||||
return x;
|
||||
|
||||
return
|
||||
x;
|
||||
|
||||
%x;
|
||||
|
||||
a[b];
|
||||
|
||||
a[
|
||||
b];
|
||||
|
||||
a.11;
|
||||
|
||||
break;
|
||||
|
||||
<> x;
|
||||
|
||||
x?;
|
||||
|
||||
// other
|
||||
|
||||
func {
|
||||
|
||||
x
|
||||
.func a b c;
|
||||
|
||||
x
|
||||
.func
|
||||
a
|
||||
b
|
||||
c;
|
||||
|
||||
Type.func a b c;
|
||||
|
||||
Type.func
|
||||
a
|
||||
b
|
||||
c;
|
||||
|
||||
Type @a x @b y @c z;
|
||||
|
||||
Type
|
||||
@a x
|
||||
@b y
|
||||
@c z;
|
||||
|
||||
\ 'x 'y 'z => x;
|
||||
|
||||
\ 'x
|
||||
'y
|
||||
'z
|
||||
=> x;
|
||||
|
||||
\ 'x 'y 'z
|
||||
=> x;
|
||||
|
||||
\ 'x
|
||||
'y
|
||||
'z
|
||||
=>
|
||||
x;
|
||||
|
||||
(x);
|
||||
|
||||
(
|
||||
x
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue