ArkScript
A small, fast, functional and scripting language for video games
Welder.cpp
Go to the documentation of this file.
1#include <Ark/Constants.hpp>
3
8#include <Ark/Files.hpp>
9#include <Ark/Exceptions.hpp>
10
11#include <sstream>
12#include <fmt/ostream.h>
13
14namespace Ark
15{
16 Welder::Welder(const unsigned debug, const std::vector<std::filesystem::path>& lib_env, const uint16_t features) :
17 m_lib_env(lib_env), m_features(features),
18 m_computed_ast(internal::NodeType::Unused),
19 m_parser(debug),
20 m_import_solver(debug, lib_env),
21 m_macro_processor(debug),
22 m_ast_optimizer(debug),
23 m_name_resolver(debug),
24 m_logger("Welder", debug),
25 m_lowerer(debug),
26 m_ir_optimizer(debug),
27 m_ir_compiler(debug)
28 {}
29
30 void Welder::registerSymbol(const std::string& name)
31 {
32 m_name_resolver.addDefinedSymbol(name, /* is_mutable= */ false);
33 }
34
35 bool Welder::computeASTFromFile(const std::string& filename)
36 {
37 m_root_file = std::filesystem::path(filename);
38 const std::string code = Utils::readFile(filename);
39
40 return computeAST(filename, code);
41 }
42
43 bool Welder::computeASTFromString(const std::string& code)
44 {
45 m_root_file = std::filesystem::current_path(); // No filename given, take the current working directory
46
47 return computeAST(ARK_NO_NAME_FILE, code);
48 }
49
51 {
52 try
53 {
56
57 if ((m_features & FeatureIROptimizer) != 0)
58 {
61 }
62
65
66 if ((m_features & FeatureDumpIR) != 0)
68
69 return true;
70 }
71 catch (const CodeError& e)
72 {
74 throw;
75
77 return false;
78 }
79 }
80
81 bool Welder::saveBytecodeToFile(const std::string& filename)
82 {
83 m_logger.info("Final bytecode size: {}B", m_bytecode.size() * sizeof(uint8_t));
84
85 if (m_bytecode.empty())
86 return false;
87
88 std::ofstream output(filename, std::ofstream::binary);
89 output.write(
90 reinterpret_cast<char*>(&m_bytecode[0]),
91 static_cast<std::streamsize>(m_bytecode.size() * sizeof(uint8_t)));
92 output.close();
93 return true;
94 }
95
96 const internal::Node& Welder::ast() const noexcept
97 {
98 return m_computed_ast;
99 }
100
101 std::string Welder::textualIR() const noexcept
102 {
103 std::stringstream stream;
105 return stream.str();
106 }
107
108 const bytecode_t& Welder::bytecode() const noexcept
109 {
110 return m_bytecode;
111 }
112
114 {
115 std::filesystem::path path = m_root_file;
116 if (is_directory(m_root_file))
117 path /= "output.ark.ir";
118 else
119 path.replace_extension(".ark.ir");
120
121 std::ofstream output(path);
123 output.close();
124 }
125
126 bool Welder::computeAST(const std::string& filename, const std::string& code)
127 {
128 try
129 {
130 m_parser.process(filename, code);
132
133 if ((m_features & FeatureImportSolver) != 0)
134 {
138 }
139
141 {
144 }
145
146 if ((m_features & FeatureNameResolver) != 0)
147 {
150 }
151
152 if ((m_features & FeatureASTOptimizer) != 0)
153 {
156 }
157
158 return true;
159 }
160 catch (const CodeError& e)
161 {
163 throw;
164
166 return false;
167 }
168 }
169}
Constants used by ArkScript.
#define ARK_NO_NAME_FILE
Definition Constants.hpp:26
ArkScript homemade exceptions.
Lots of utilities about the filesystem.
Handle imports, resolve them with modules and everything.
Resolves names and fully qualify them in the AST (prefixing them with the package they are from)
Optimizes a given ArkScript AST.
Handles the macros and their expansion in ArkScript source code.
In charge of welding everything needed to compile code.
bool computeAST(const std::string &filename, const std::string &code)
Definition Welder.cpp:126
internal::ImportSolver m_import_solver
Definition Welder.hpp:96
internal::Node m_computed_ast
Definition Welder.hpp:93
Welder(unsigned debug, const std::vector< std::filesystem::path > &lib_env, uint16_t features=DefaultFeatures)
Create a new Welder.
Definition Welder.cpp:16
internal::IROptimizer m_ir_optimizer
Definition Welder.hpp:103
void registerSymbol(const std::string &name)
Register a symbol as a global in the compiler.
Definition Welder.cpp:30
bool computeASTFromString(const std::string &code)
Definition Welder.cpp:43
std::string textualIR() const noexcept
Definition Welder.cpp:101
internal::Logger m_logger
Definition Welder.hpp:101
std::vector< internal::IR::Block > m_ir
Definition Welder.hpp:91
internal::NameResolutionPass m_name_resolver
Definition Welder.hpp:99
std::filesystem::path m_root_file
Definition Welder.hpp:89
internal::ASTLowerer m_lowerer
Definition Welder.hpp:102
const bytecode_t & bytecode() const noexcept
Definition Welder.cpp:108
internal::Parser m_parser
Definition Welder.hpp:95
internal::IRCompiler m_ir_compiler
Definition Welder.hpp:104
internal::MacroProcessor m_macro_processor
Definition Welder.hpp:97
bool saveBytecodeToFile(const std::string &filename)
Save the generated bytecode to a given file.
Definition Welder.cpp:81
bool generateBytecode()
Compile the AST processed by computeASTFromFile / computeASTFromString.
Definition Welder.cpp:50
bool computeASTFromFile(const std::string &filename)
Definition Welder.cpp:35
uint16_t m_features
Definition Welder.hpp:87
internal::Optimizer m_ast_optimizer
Definition Welder.hpp:98
void dumpIRToFile() const
Definition Welder.cpp:113
bytecode_t m_bytecode
Definition Welder.hpp:92
const internal::Node & ast() const noexcept
Definition Welder.cpp:96
const std::vector< ValTableElem > & values() const noexcept
Return the value table pre-computed.
const std::vector< IR::Block > & intermediateRepresentation() const noexcept
Return the IR blocks (one per scope)
void process(const Node &ast)
Start the compilation.
const std::vector< std::string > & symbols() const noexcept
Return the symbol table pre-computed.
void dumpToStream(std::ostream &stream) const
Dump the IR given to process to an output stream.
const bytecode_t & bytecode() const noexcept
Return the constructed bytecode object.
void process(const std::vector< IR::Block > &pages, const std::vector< std::string > &symbols, const std::vector< ValTableElem > &values)
Turn a given IR into bytecode.
const std::vector< IR::Block > & intermediateRepresentation() const noexcept
Return the IR blocks (one per scope)
void process(const std::vector< IR::Block > &pages, const std::vector< std::string > &symbols, const std::vector< ValTableElem > &values)
Turn a given IR into bytecode.
void process(const Node &origin_ast) override
Start processing the given AST.
ImportSolver & setup(const std::filesystem::path &root, const std::vector< Import > &origin_imports)
Configure the ImportSolver.
const Node & ast() const noexcept override
Output of the compiler pass.
void info(const char *fmt, Args &&... args)
Write an info level log using fmtlib.
Definition Logger.hpp:47
const Node & ast() const noexcept override
Return the modified AST.
Definition Processor.cpp:45
void process(const Node &ast) override
Send the complete AST and work on it.
Definition Processor.cpp:30
const Node & ast() const noexcept override
Unused overload that return the input AST (untouched as this pass only generates errors)
void process(const Node &ast) override
Start visiting the given AST, checking for mutability violation and unbound variables.
std::string addDefinedSymbol(const std::string &sym, bool is_mutable)
Register a symbol as defined, so that later we can throw errors on undefined symbols.
A node of an Abstract Syntax Tree for ArkScript.
Definition Node.hpp:30
const Node & ast() const noexcept override
Returns the modified AST.
Definition Optimizer.cpp:28
void process(const Node &ast) override
Send the AST to the optimizer, then run the different optimization strategies on it.
Definition Optimizer.cpp:9
void process(const std::string &filename, const std::string &code)
Parse the given code.
Definition Parser.cpp:51
const Node & ast() const noexcept
Definition Parser.cpp:95
const std::vector< Import > & imports() const
Definition Parser.cpp:100
ARK_API void generate(const CodeError &e, std::ostream &os=std::cout, bool colorize=true)
Generate a diagnostic from an error and print it to the standard output.
std::string readFile(const std::string &name)
Helper to read a file.
Definition Files.hpp:47
NodeType
The different node types available.
Definition Common.hpp:44
constexpr uint16_t FeatureImportSolver
Definition Constants.hpp:48
constexpr uint16_t FeatureIROptimizer
Definition Constants.hpp:51
constexpr uint16_t FeatureMacroProcessor
Definition Constants.hpp:49
constexpr uint16_t FeatureTestFailOnException
This feature should only be used in tests, to disable diagnostics generation and enable exceptions to...
Definition Constants.hpp:56
std::vector< uint8_t > bytecode_t
Definition Common.hpp:22
constexpr uint16_t FeatureASTOptimizer
This is disabled so that embedding ArkScript does not prune nodes from the AST ; it is active in the ...
Definition Constants.hpp:50
constexpr uint16_t FeatureDumpIR
Definition Constants.hpp:54
constexpr uint16_t FeatureNameResolver
Definition Constants.hpp:52
CodeError thrown by the compiler (parser, macro processor, optimizer, and compiler itself)