basic printers, type printers, some fixes, part of expression printers

This commit is contained in:
ProgramSnail 2023-07-24 18:47:57 +03:00
parent 3914ff7d8b
commit 3669084f55
14 changed files with 795 additions and 39 deletions

View file

@ -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_;
};

View 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

View file

@ -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 {

View 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

View file

@ -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
View 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