Skip to content

Commit

Permalink
started work on codegen emitters, changed a and fixed a few things in…
Browse files Browse the repository at this point in the history
… nodes and started work on AST context
  • Loading branch information
Ze7111 committed Jul 5, 2024
1 parent 1f494ef commit 4f6256a
Show file tree
Hide file tree
Showing 8 changed files with 347 additions and 3 deletions.
211 changes: 211 additions & 0 deletions source/generator/include/cxx_emitter.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/**
* @author Dhruvan Kartik
* @copyright Copyright (c) 2024 (CC BY 4.0)
*
* @note This code is part of the Helix Language Project and is licensed under the Attribution 4.0
* International license (CC BY 4.0). You are allowed to use, modify, redistribute, and create
* derivative works, even for commercial purposes, provided that you give appropriate credit,
* provide a link to the license, and indicate if changes were made. For more information, please
* visit: https://creativecommons.org/licenses/by/4.0/ SPDX-License-Identifier: CC-BY-4.0
*
* @note This code is provided by the creators of Helix. Visit our website at:
* https://helix-lang.com/ for more information.
*/
#ifndef __CXX_EMITTER_H__
#define __CXX_EMITTER_H__

#include <cstddef>
#include <cstdlib>
#include <expected>
#include <memory>
#include <string>
#include <vector>

#include "core/types/hx_ints"
#include "parser/ast/include/ast.hh"
#include "parser/ast/include/context.hh"


/* usage
#include "generator/include/cxx_emitter.hh"
using namespace codegen::cxx;
CXXBuilder builder = CXXBuilder(ast::node::Program, Context);
CXXBody built = builder.generate();
CXXNodeList functions = built.get_functions(include_priv: false));
CXXNodeList classes = built.get_classes (include_priv: false));
CXXNodeList structs = built.get_structs (include_priv: false));
CXXNodeList enums = built.get_enums (include_priv: false));
CXXNodeList unions = built.get_unions (include_priv: false));
CXXNodeList types = built.get_types (include_priv: false));
CXXNodeList variables = built.get_variables(include_priv: false));
CXXNodeList constants = built.get_constants(include_priv: false));
built.to_code(); // the whole ir code
std::string current_namespace;
std::string header;
for (auto &const fn : functions) {
if (current_namespace != fn->parent().to_code()) {
if (!current_namespace.empty()) {
header += "} \\ end namespace " + current_namespace + "\n";
}
header += "namespace " + fn->parent().to_code() + "{\n";
}
header += fn->signature().to_code() + ";\n"; // int some_func();
}
for the example ast (10 + (9 + 1)):
{
"BinaryExpr" : {
"type": "expr",
"op": "+",
"left": {
"type": "literal",
"value": "10"
},
"right": {
"BinaryExpr" : {
"type": "expr",
"op": "+",
"left": {
"type": "literal",
"value": "9"
},
"right": {
"type": "literal",
"value": "1"
}
}
}
}
}
CXXNodeList = [
BinaryExprBuilder(
op: "+",
left: *BuilderLiteralInt(10),
right: *BinaryExprBuilder(
op: "+",
left: *BuilderLiteralInt(9),
right: *BuilderLiteralInt(1)
)
)
]
CXXNodeList[0].to_string();
*/

namespace codegen::cxx {
using namespace parser;

template <typename T>
struct CXXNode;

template <typename T = void>
using CXXNodePtr = std::shared_ptr<CXXNode<T>>;

template <>
struct CXXNode<void> {
CXXNode() = default;
CXXNode(CXXNode &&) = default;
CXXNode(const CXXNode &) = default;
CXXNode &operator=(CXXNode &&) = default;
CXXNode &operator=(const CXXNode &) = delete;
virtual ~CXXNode() = default;

CXXNodePtr<> get_parent();
CXXNodePtr<> get_signature();
CXXNodePtr<> get_body();
CXXNodePtr<> generate();

std::string to_code(); // emit entire object as a string
std::string to_stub(); // emit only signature as a string
std::string to_json();
};

template <typename T>
struct CXXNode : public CXXNode<void> {
CXXNode(ast::NodePtr<> &ast, ast::Context &context);
CXXNode() = default;
CXXNode(CXXNode &&) = default;
CXXNode(const CXXNode &) = default;
CXXNode &operator=(CXXNode &&) = default;
CXXNode &operator=(const CXXNode &) = delete;
~CXXNode() = default;
};

template <typename T = void>
struct CXXNodeList {
explicit CXXNodeList(const std::string &file_name);
CXXNodeList() = default;
CXXNodeList(CXXNodeList &&) = default;
CXXNodeList(const CXXNodeList &) = default;
CXXNodeList &operator=(CXXNodeList &&) = default;
CXXNodeList &operator=(const CXXNodeList &) = delete;
~CXXNodeList() = default;

void append(CXXNodePtr<T> node);
void append_front(CXXNodePtr<T> node);

CXXNodePtr<T> pop(u32 n);
void remove(u32 n);
void clear();

std::string to_code();
std::string to_stub();
std::string to_json();

private:
std::string filename;
std::vector<CXXNodePtr<T>> nodes;
};

struct CXXBody {
CXXBody() = default;
CXXBody(CXXBody &&) = default;
CXXBody(const CXXBody &) = default;
CXXBody &operator=(CXXBody &&) = default;
CXXBody &operator=(const CXXBody &) = delete;
~CXXBody() = default;

CXXNodeList< /*FunctionNode*/> get_functions(bool include_priv = false);
CXXNodeList< /*VariableNode*/> get_variables(bool include_priv = false);
CXXNodeList< /*ConstantNode*/> get_constants(bool include_priv = false);
CXXNodeList< /*ClassNode*/ > get_classes (bool include_priv = false);
CXXNodeList< /*StructNode*/ > get_structs (bool include_priv = false);
CXXNodeList< /*UnionNode*/ > get_unions (bool include_priv = false);
CXXNodeList< /*EnumNode*/ > get_enums (bool include_priv = false);
CXXNodeList< /*TypeNode*/ > get_types (bool include_priv = false);

std::string to_code();
std::string to_stub();
std::string to_json();

private:
friend void generate_from_node(ast::NodePtr<> node);
};

struct CXXBuilder {
CXXBuilder() = delete;
CXXBuilder(CXXBuilder &&) = default;
CXXBuilder(const CXXBuilder &) = default;
CXXBuilder &operator=(CXXBuilder &&) = delete;
CXXBuilder &operator=(const CXXBuilder &) = delete;
~CXXBuilder() = default;

CXXBody generate();

private:
ast::node::Program& AST;
ast::Context& context;
};
}

#endif // __CXX_EMITTER_H__
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@
* @note This code is provided by the creators of Helix. Visit our website at:
* https://helix-lang.com/ for more information.
*/
#ifndef __LLVM_EMITTER_H__
#define __LLVM_EMITTER_H__

namespace codegen::llvm {

}

#endif // __LLVM_EMITTER_H__
21 changes: 21 additions & 0 deletions source/generator/include/py_emitter.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @author Dhruvan Kartik
* @copyright Copyright (c) 2024 (CC BY 4.0)
*
* @note This code is part of the Helix Language Project and is licensed under the Attribution 4.0
* International license (CC BY 4.0). You are allowed to use, modify, redistribute, and create
* derivative works, even for commercial purposes, provided that you give appropriate credit,
* provide a link to the license, and indicate if changes were made. For more information, please
* visit: https://creativecommons.org/licenses/by/4.0/ SPDX-License-Identifier: CC-BY-4.0
*
* @note This code is provided by the creators of Helix. Visit our website at:
* https://helix-lang.com/ for more information.
*/
#ifndef __PYTHON_EMITTER_H__
#define __PYTHON_EMITTER_H__

namespace codegen::python {

}

#endif // __PYTHON_EMITTER_H__
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@
* @note This code is provided by the creators of Helix. Visit our website at:
* https://helix-lang.com/ for more information.
*/
#ifndef __RUST_EMITTER_H__
#define __RUST_EMITTER_H__

namespace codegen::rust {

}

#endif // __RUST_EMITTER_H__
75 changes: 75 additions & 0 deletions source/parser/ast/include/ast.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* @author Dhruvan Kartik
* @copyright Copyright (c) 2024 (CC BY 4.0)
*
* @note This code is part of the Helix Language Project and is licensed under the Attribution 4.0
* International license (CC BY 4.0). You are allowed to use, modify, redistribute, and create
* derivative works, even for commercial purposes, provided that you give appropriate credit,
* provide a link to the license, and indicate if changes were made. For more information, please
* visit: https://creativecommons.org/licenses/by/4.0/ SPDX-License-Identifier: CC-BY-4.0
*
* @note This code is provided by the creators of Helix. Visit our website at:
* https://helix-lang.com/ for more information.
*/
#ifndef __AST_HH__
#define __AST_HH__

#include <concepts>
#include <cstddef>
#include <cstdlib>
#include <expected>
#include <functional>
#include <memory>
#include <string>
#include <vector>

#include "token/include/token_list.hh"

namespace parser::ast {
struct ParseError {};

using TokenListRef = std::shared_ptr<token::TokenList>;
using ParseResult = std::expected<u64, ParseError>; // len of tokens to skip | recoverable error

template <typename T>
struct ASTBase;

template <>
struct ASTBase<void> {
// virtual std::expected<std::span<Token>,AstError> parse(std::span<Token> tokens) = 0;
ASTBase() = default;
ASTBase(ASTBase &&) = default;
ASTBase(const ASTBase &) = default;
ASTBase &operator=(ASTBase &&) = default;
ASTBase &operator=(const ASTBase &) = delete;
virtual ~ASTBase() = default;

[[nodiscard]] virtual ParseResult parse() = 0;
[[nodiscard]] virtual std::string to_json(u32 depth = 0) const = 0;
};

template <typename T>
struct ASTBase : public ASTBase<void> {
explicit ASTBase(TokenListRef parse_tokens);
ASTBase() = default;
ASTBase(ASTBase &&) = default;
ASTBase(const ASTBase &) = default;
ASTBase &operator=(ASTBase &&) = default;
ASTBase &operator=(const ASTBase &) = delete;
~ASTBase() = default;
};

template <typename T = void>
concept ASTNode = std::derived_from<T, ASTBase<T>>;

template <typename T = void>
using NodePtr = std::shared_ptr<ASTBase<T>>;

template <typename T = void>
using NodeList = std::vector<NodePtr<T>>;

template <typename T = void>
using Slice = const std::reference_wrapper<NodeList<T>>;

} // namespace parser::ast
#endif // __AST_HH__
4 changes: 2 additions & 2 deletions source/parser/ast/include/context.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

#include "parser/ast/include/nodes.hh"

namespace ast {
class ASTContext {};
namespace parser::ast {
class Context {};
} // namespace ast

#endif // __CONTEXT_HH__
23 changes: 23 additions & 0 deletions source/parser/ast/include/nodes.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @author Dhruvan Kartik
* @copyright Copyright (c) 2024 (CC BY 4.0)
*
* @note This code is part of the Helix Language Project and is licensed under the Attribution 4.0
* International license (CC BY 4.0). You are allowed to use, modify, redistribute, and create
* derivative works, even for commercial purposes, provided that you give appropriate credit,
* provide a link to the license, and indicate if changes were made. For more information, please
* visit: https://creativecommons.org/licenses/by/4.0/ SPDX-License-Identifier: CC-BY-4.0
*
* @note This code is provided by the creators of Helix. Visit our website at:
* https://helix-lang.com/ for more information.
*/
#ifndef __NODES_H__
#define __NODES_H__

#include "parser/ast/include/ast.hh"

namespace parser::ast::node {
struct Program : ASTBase<Program> {};
}

#endif // __NODES_H__
2 changes: 1 addition & 1 deletion source/parser/cst/include/cst.hh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct CSTBase<void> {
CSTBase(const CSTBase &) = default;
CSTBase &operator=(CSTBase &&) = default;
CSTBase &operator=(const CSTBase &) = delete;
~CSTBase() = default;
virtual ~CSTBase() = default;

[[nodiscard]] virtual ParseResult parse() = 0;
[[nodiscard]] virtual std::string to_json(u32 depth = 0) const = 0;
Expand Down

0 comments on commit 4f6256a

Please sign in to comment.