interpreter_tree first iteration

This commit is contained in:
ProgramSnail 2023-03-26 15:20:53 +03:00
parent 7f4cd5ee9a
commit 1ba132bb06
15 changed files with 1829 additions and 1 deletions

View file

43
include/contexts.hpp Normal file
View file

@ -0,0 +1,43 @@
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
// for clangd
#include "symbols_info.hpp"
namespace info {
class ContextManager {
public:
void CallFunction(const std::vector<VariableInfo>&);
void EnterContext();
void ExitContext();
void DefineVariable(const VariableInfo& variable);
void ChangeVariableValue(const std::string& name, const Value& new_value);
const Value& GetVariableValue(const std::string& name);
private:
class Context {
public:
Context(bool hide_previous = false) : hide_previous_(hide_previous) {}
void DefineVariable(const VariableInfo& variable);
void ChangeVaraibleValue(const std::string& name, const Value& neew_value);
const Value& GetVariableValue(const std::string& name);
bool IsFirst() { return hide_previous_; }
private:
bool hide_previous_;
std::unordered_map<std::string, VariableInfo> variables_;
};
// TODO handle current namespace (for class names, function names, etc.)
// TODO ?? are global variables forbidden ??
Context global_context_;
std::vector<Context> contexts_;
};
} // namespace info

View file

View file

25
include/global_info.hpp Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include <string>
#include <unordered_map>
// for clangd
#include "symbols_info.hpp"
namespace info {
class GlobalInfo {
public:
GlobalInfo();
// ?? EnterNamespace / ExitNamespace ??
// concurrent work ??
// AddType, AddFunction
// TODO
private:
std::unordered_map<std::string, NamespaceInfo> namespaces_;
NamespaceInfo global_namespace_;
// lock for concurrency ??
};
} // namespace info

View file

@ -0,0 +1,549 @@
#pragma once
#include <string>
#include <vector>
#include <variant>
#include <memory>
// for clangd
#include "node.hpp"
namespace interpreter {
namespace tokens {
// ----------------- Declarations -----------------
using AnyIdentifier = std::string;
using NameOrOperatorIdentifier = std::string;
using NameIdentifier = std::string;
using AnyTypeIdentifier = std::string;
using TypeIdentifier = std::string;
using AbstractTypeIdentifier = std::string;
using OperatorIdentifier = std::string;
using TypeclassIdentifier = std::string;
// Sources -----------------
struct SourceFile; // TODO partitions
struct Sources;
// Namespaces, partittions -----------------
struct Partition;
struct Namespace;
// Definitions -----------------
struct ImportStatement;
struct UsageDefinition;
struct AliasDefinition;
struct VariableDefinition;
struct FunctionDeclaration;
struct FunctionDefinition;
struct AliasTypeDefinition; // | Parts of type definition
struct TypeDefinition; // |
struct TypeclassDefinition;
using SourceStatement = std::variant<
ImportStatement,
UsageDefinition,
AliasDefinition,
VariableDefinition, // ??
FunctionDeclaration,
FunctionDefinition,
AliasTypeDefinition,
TypeDefinition,
TypeclassDefinition,
Namespace>;
// Definition parts
struct ParametrizedType;
struct TupleType;
struct VariantType;
struct ParametrizedTypeclass;
using FunctionDeclarationType = std::variant<
ParametrizedType,
TupleType,
VariantType,
ParametrizedTypeclass>;
struct DefinedName;
struct DefinedAnnotatedName;
struct DefinedType;
struct DefinedTypeclass;
struct DefinitionParameter;
struct DefinitionArgument;
// Flow control -----------------
struct Match;
struct Condition;
struct WhileLoop; // WhileLoop <-> DoWhileLoop
struct ForLoop;
struct LoopLoop;
using FlowControl = std::variant<
Match,
Condition,
WhileLoop,
ForLoop,
LoopLoop>;
// Statements, expressions, blocks, etc. -----------------
struct Block;
//
struct NameExpression;
struct ScopedStatement;
using SubExpressionToken = std::variant<
NameExpression,
ScopedStatement>;
//
struct FunctionCallExpression;
struct BinaryOperatorExpression;
using SubExpression = std::variant<
FunctionCallExpression,
BinaryOperatorExpression,
SubExpressionToken>;
//
struct ReturnExpression;
enum class LoopControlExpression {
Break,
Continue,
};
using PrefixedExpression = std::variant<
ReturnExpression,
LoopControlExpression,
Block>;
//
struct LambdaFunction;
struct TypeConstructor;
struct UnaryOperatorExpression;
using Expression = std::variant<
LambdaFunction,
TypeConstructor,
PrefixedExpression,
UnaryOperatorExpression,
SubExpression>;
//
struct TupleExpression;
struct VariantExpression;
using SuperExpression = std::variant<
FlowControl,
TupleExpression,
VariantExpression,
Expression>;
//
struct ScopedStatement; // ?? scoped statement is _superexpression ??
// Operators
struct BinaryOperatorExpression;
struct UnaryOperatorExpression;
// Simple Expressions
struct FunctionCallExpression;
struct TupleExpression;
struct VariantExpression;
struct ReturnExpression;
// Lambda
struct LambdaFunction;
// Name
struct NameSuperExpression;
struct NameExpression;
struct TupleName;
struct VariantName;
struct AnnotatedName;
using AnyName = std::variant<
AnnotatedName,
TupleName,
VariantName>;
// Type
struct TypeConstructor;
// // TypeOrAnyType <-> AnyType
struct TupleType;
struct VariantType;
struct VariantType;
using AnyType = std::variant<
ParametrizedType,
TupleType,
VariantType>;
// // TypeIdentifierDefinition <-> some '.' + TypeIdentifier
using TypeIdentifierDefinition = std::string;
struct AnnotatedType;
// // TypeAnnotations - inplace ??
struct ParametrizedType;
struct TypeExpression;
using TypeSubExpression = std::variant<
AnyTypeIdentifier,
ParametrizedType>;
// Typeclass
struct AnnotatedTypeclass;
struct ParametrizedTypeclass;
struct TypeclassExpression;
// Comments [IGNORE] -----------------
// Identifiers, constants, etc. -----------------
struct FloatNumberLiteral;
struct NumberLiteral;
struct StringLiteral;
struct CharLiteral;
using Literal = std::variant<
FloatNumberLiteral,
NumberLiteral,
StringLiteral,
CharLiteral>;
//
using NameSubSuperExpression = std::variant<
NameIdentifier,
Literal,
SuperExpression>;
// ----------------- Sources -----------------
struct SourceFile : public Node {
std::vector<std::variant<SourceStatement, Partition>> statements;
};
struct Sources : public Node {
std::vector<SourceStatement> statemets;
};
// ----------------- Namespaces, partittions -----------------
struct Partition : public Node {
enum class PartitionType {
Test,
Interface,
Core,
Lib,
Module, // rename ??
Exe,
};
PartitionType type;
std::unique_ptr<Sources> scope;
};
struct Namespace : public Node {
std::unique_ptr<std::variant<DefinedAnnotatedName, DefinedType>> name;
// TODO add const / var specification
std::unique_ptr<Sources> scope;
};
// ----------------- Definitions -----------------
struct ImportStatement : public Node {
std::string module_name;
std::vector<AnyIdentifier> symbols; // TODO parametric import support
};
struct UsageDefinition : public Node {
TypeIdentifier module_identifier;
std::unique_ptr<ImportStatement> import_statement;
};
struct AliasDefinition : public Node {
std::unique_ptr<DefinedType> name;
std::unique_ptr<ParametrizedType> value;
};
struct VariableDefinition : public Node {
NameIdentifier name;
std::unique_ptr<SuperExpression> value;
};
struct FunctionDeclaration : public Node {
NameIdentifier name;
std::vector<std::unique_ptr<FunctionDeclarationType>> argument_types;
};
struct FunctionDefintion : public Node {
std::unique_ptr<DefinedName> name;
std::unique_ptr<SuperExpression> value;
};
struct AliasTypeDefinition : public Node {
std::unique_ptr<DefinedType> name;
std::unique_ptr<ParametrizedType> value;
};
struct TypeDefinition : public Node {
std::unique_ptr<DefinedType> name;
std::unique_ptr<AnyType> value;
};
struct TypeclassDefinition : public Node {
std::unique_ptr<DefinedTypeclass> name;
std::vector<std::unique_ptr<FunctionDeclaration>> requirements;
};
// Definition parts -----------------
struct DefinedName : public Node {
bool is_operator = false; // other format ??
NameOrOperatorIdentifier name; // function name or operator
std::vector<std::unique_ptr<DefinitionParameter>> parameters;
std::vector<std::unique_ptr<DefinitionArgument>> arguments;
};
struct DefinedAnnotatedName : public Node {
NameIdentifier name;
std::unique_ptr<std::variant<DefinedType, DefinedTypeclass>> type;
};
struct DefinedType : public Node {
std::unique_ptr<AnnotatedType> type;
std::vector<std::unique_ptr<DefinitionParameter>> parameters;
std::vector<std::unique_ptr<DefinitionArgument>> arguments;
};
struct DefinedTypeclass : public Node {
std::unique_ptr<AnnotatedTypeclass> typeclass;
std::vector<std::unique_ptr<DefinitionParameter>> parameters;
std::vector<std::unique_ptr<DefinitionArgument>> arguments;
};
struct DefinitionParameter : public Node {
AbstractTypeIdentifier abstract_type;
std::vector<std::unique_ptr<ParametrizedTypeclass>> typeclasses;
};
struct DefinitionArgument : public Node {
NameIdentifier name;
std::vector<std::unique_ptr<ParametrizedType>> types;
};
// ----------------- Flow control -----------------
struct MatchCase {
std::unique_ptr<Expression> value;
std::unique_ptr<Expression> condition;
std::unique_ptr<Expression> statement;
};
struct Match : public Node {
std::unique_ptr<Expression> value;
std::vector<MatchCase> matches;
};
struct Condition : public Node {
std::vector<std::unique_ptr<Expression>> conditions; // if, elif
std::vector<std::unique_ptr<Expression>> stetemets; // if, elif, else
};
struct WhileLoop : public Node { // WhileLoop <-> DoWhileLoop
std::unique_ptr<Expression> condition;
std::unique_ptr<Expression> statement;
};
struct ForLoop : public Node {
std::unique_ptr<AnyName> variable;
std::unique_ptr<Expression> interval;
std::unique_ptr<Expression> statement;
};
struct LoopLoop : public Node {
std::unique_ptr<Expression> statement;
};
// ----------------- Statements, expressions, blocks, etc. -----------------
using BlockStatement = std::variant<
Expression,
AliasDefinition,
VariableDefinition,
FlowControl,
PrefixedExpression>;
struct Block : public Node {
std::vector<std::unique_ptr<BlockStatement>> statements;
};
struct ScopedStatement : public Node {
std::unique_ptr<SuperExpression> statement;
};
// Operators -----------------
struct BinaryOperatorExpression : public Node {
OperatorIdentifier operator_name;
std::unique_ptr<SubExpression> left_expression;
std::unique_ptr<SubExpression> right_expression;
};
struct UnaryOperatorExpression : public Node { // TODO fix prescendence
OperatorIdentifier operator_name;
std::unique_ptr<Expression> expression;
};
// Simple Expressions -----------------
using FunctionArgument = std::variant<SubExpressionToken, TypeSubExpression>;
struct FunctionCallExpression : public Node {
std::unique_ptr<NameSuperExpression> name;
std::vector<std::unique_ptr<FunctionArgument>> arguments;
};
struct TupleExpression : public Node {
std::vector<std::unique_ptr<SubExpression>> expressions;
};
struct VariantExpression : public Node {
std::vector<std::unique_ptr<SubExpression>> expressions;
};
struct ReturnExpression : public Node {
std::unique_ptr<Expression> expression;
};
// Lambda -----------------
struct LambdaFunction : public Node {
std::vector<std::unique_ptr<DefinitionParameter>> parameters;
std::vector<std::unique_ptr<DefinitionArgument>> arguments;
std::unique_ptr<Expression> expression;
};
// Name -----------------
struct NameSuperExpression : public Node {
std::vector<std::unique_ptr<TypeSubExpression>> namespaces;
std::vector<std::unique_ptr<NameSubSuperExpression>> expressions; // last is not SuperExpression
};
struct NameExpression : public Node {
std::vector<TypeSubExpression> namespaces;
std::vector<NameIdentifier> names;
};
struct TupleName : public Node {
std::vector<std::unique_ptr<AnnotatedName>> names;
};
struct VariantName : public Node {
std::vector<std::unique_ptr<AnnotatedName>> names;
};
struct AnnotatedName : public Node {
NameIdentifier name;
std::unique_ptr<ParametrizedType> type; // optional
};
// TODO ?? mark all optional fields ??
// Type -----------------
struct TypeConstructor : public Node {
std::unique_ptr<ParametrizedType> type;
std::vector<std::pair<NameIdentifier, std::unique_ptr<SubExpression>>> parameters;
};
struct TupleType : public Node {
TypeIdentifierDefinition type; // optional
std::vector<std::pair<NameIdentifier, std::unique_ptr<AnyType>>> entities; // NameIdentifier is optional
};
struct VariantType : public Node {
TypeIdentifierDefinition type; // optional
std::vector<std::pair<TypeIdentifierDefinition, std::unique_ptr<TupleType>>> constructors;
};
struct AnnotatedType : public Node {
std::unique_ptr<TypeExpression> type_expression;
std::vector<std::unique_ptr<ParametrizedTypeclass>> annotations;
};
using TypeParameter = std::variant<ParametrizedType, Expression>;
struct ParametrizedType : public Node {
std::unique_ptr<TypeExpression> type_expression;
std::vector<std::unique_ptr<TypeParameter>> parameters;
};
struct TypeExpression : public Node {
std::vector<std::unique_ptr<TypeSubExpression>> namespaces;
AnyTypeIdentifier type;
};
// Typeclass -----------------
struct AnnotatedTypeclass : public Node {
std::unique_ptr<TypeclassExpression> typeclass_expression;
std::vector<std::unique_ptr<ParametrizedTypeclass>> annotations;
};
struct ParametrizedTypeclass : public Node {
std::unique_ptr<TypeclassExpression> typeclass_expression;
std::vector<std::unique_ptr<TypeParameter>> parameters;
};
struct TypeclassExpression : public Node {
std::vector<std::unique_ptr<TypeSubExpression>> namespaces;
TypeclassIdentifier typeclass;
};
// ----------------- Comments [IGNORE] -----------------
// ----------------- Identifiers, constants, etc. -----------------
struct FloatNumberLiteral : public Node {
double value;
};
struct NumberLiteral : public Node {
int64_t value;
};
struct StringLiteral : public Node {
std::string value;
};
struct CharLiteral : public Node {
char value;
};
} // namespace tokens
} // namespace interpereter

36
include/node.hpp Normal file
View file

@ -0,0 +1,36 @@
#pragma once
#include <cstddef>
// for clangd
#include "parse_tree.hpp"
namespace info {
class GlobalInfo;
class Context;
} // namespace info
namespace interpreter {
class Visitor;
struct Node {
//public:
Node(info::GlobalInfo& global_info) : global_info_(global_info) {}
virtual void Accept(Visitor* visitor);
/* ------------ use visitor instead ------------
virtual void build(parser::ParseTree::Cursor& cursor) = 0; // build tree from parse tree
virtual void find_symbols() = 0; // find types, typeclasses, namespaces, ..
virtual void assign_types() = 0; // typecheck
virtual void execute(info::Context& context) = 0; // execute part of tree
*/
/*private:
size_t start_position_; // ??
size_t end_position_; // ??
Node* parent_; // ??
info::GlobalInfo& global_info_;*/
};
} // namespace interpreter

64
include/parse_tree.hpp Normal file
View file

@ -0,0 +1,64 @@
#pragma once
#include <string>
// for clangd
#include "tree_sitter/api.h"
namespace parser {
class ParseTree {
public:
class Node {
public:
Node() = delete;
std::string GetType();
std::pair<size_t, size_t> GetStartPoint();
std::pair<size_t, size_t> GetEndPoint();
std::string GetAsSExpression();
bool IsNull();
bool IsNamed();
bool IsMissing();
bool IsExtra(); // comments, etc.
bool HasError();
Node NthChild(size_t n);
size_t ChildCount();
Node NthNamedChild(size_t n);
size_t NamedChildCount();
Node ChildByName(const std::string& name);
// ?? use field id instaed of name ??
// ?? node equality check needed ??
private:
TSNode node_;
};
class Cursor {
public:
Cursor(const Node& node);
void ResetTo(const Node& node);
Node GetCurrentNode();
std::string GetCurrentNodeName();
bool GoToParent();
bool GoToNextSibling();
bool GoToFirstChild();
private:
TSTreeCursor cursor_;
};
ParseTree(const std::string& input);
Node GetRoot();
private:
TSTree* tree_;
};
} // namespace parser

96
include/symbols_info.hpp Normal file
View file

@ -0,0 +1,96 @@
#pragma once
#include <string>
#include <variant>
#include <optional>
#include <vector>
#include <unordered_map>
// for clangd
namespace interpreter {
class Node;
} // namespace interpreter
namespace info {
using NumberValue = long long;
using FloatNumberValue = float;
using StringValue = std::string;
struct SimpleValue {
std::variant<NumberValue, FloatNumberValue, StringValue> value;
};
struct Value {
enum class ValueStructure {
Simple, // one value
Variant, // one value from list, can have arguments
// MultiVariant, // constructed variant // ??
Tuple, // tuple of values
};
ValueStructure structure;
std::vector<std::variant<SimpleValue, Value>> values;
};
// better variant value storage (then string) ??
struct Info {
std::string name;
};
struct VariantTypeInfo;
struct TupleTypeInfo;
struct AliasTypeInfo;
enum class BuiltInTypeInfo {
StringT,
IntT,
FloatT,
};
using TypeInfo = std::variant<VariantTypeInfo, TupleTypeInfo, AliasTypeInfo, BuiltInTypeInfo>;
struct VariableInfo : public Info {
Value value;
TypeInfo* type = nullptr;
};
// TODO lambda functions as values
// TODO aliases ??
struct TupleTypeInfo : public Info {
std::vector<std::pair<std::optional<std::string>, TypeInfo>> fields;
};
struct VariantTypeInfo : public Info {
std::vector<std::variant<std::string, TupleTypeInfo>> constructors;
// ?? any type instead of tuple type ??
};
struct AliasTypeInfo : public Info {
bool isAnotherType; // = true by default ??
TypeInfo* type = nullptr;
};
struct TypeclassInfo : public Info {
// TODO
};
struct PointerInfo {
VariableInfo* variable;
};
struct FunctionInfo : public Info {
interpreter::Node* definition;
std::vector<VariableInfo> args;
// add requirements ??
};
struct NamespaceInfo : public Info {
std::unordered_map<std::string, TypeInfo> types;
std::unordered_map<std::string, VariableInfo> variables;
std::unordered_map<std::string, FunctionInfo> functions;
std::unordered_map<std::string, NamespaceInfo> namespaces;
};
} // namespace info

View file

16
include/visitor.hpp Normal file
View file

@ -0,0 +1,16 @@
#pragma once
// for clangd
#include "interpreter_tree.hpp"
namespace interpreter {
class Visitor {
public:
virtual void Visit(Node* node) = 0; // ??
// visit(SomethingNode node)
// ...
private:
};
} // namespace interpreter