Skip to content

Commit

Permalink
refactor(def_class_visitor): capture directives to codefiles
Browse files Browse the repository at this point in the history
  • Loading branch information
JaDogg committed Mar 16, 2024
1 parent d3dbc1e commit 9c669c0
Show file tree
Hide file tree
Showing 10 changed files with 1,159 additions and 59 deletions.
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

## Licensing

* By contributing, you agree to the LICENSE of this repository. (GPLv3 + extra terms -- for compiler, MIT for libraries, various for runtime libraries).
* Your code will be bound by the same LICENSE in particular subfolder.
* Main developer - `Bhathiya Perera` holds the right to dual license any future versions of Yaksha (compiler, binary distribution, etc) as needed.
* Main developer - `Bhathiya Perera` may relicense Yaksha (compiler, binary distribution, etc) to a different open source license.
* By contributing, you agree to the LICENCE of this repository. (GPLv3 + extra terms -- for compiler, MIT for libraries, various for runtime libraries).
* Your code will be bound by the same LICENCE in particular sub-folder.
* Main developer - `Bhathiya Perera` holds the right to dual licence any future versions of Yaksha (compiler, binary distribution, etc) as needed.
* Main developer - `Bhathiya Perera` may license Yaksha (compiler, binary distribution, etc) to a different open source licence.
* Donations or contributions does not grant you ability to redistribute / repackage without agreeing to GPLv3 + extra terms. (Unless you are explicitly allowed)
* Any new C library added to runtime needs to be properly attributed to original authors.

## Demos
## Demos / Projects built with Yaksha

* Example if you build a game or CLI tool you can license it however you want.
* If you get it working with WASM, consider adding it to the demos. (If so please put your name / github account in the PR to the website repo)
Expand Down
2 changes: 1 addition & 1 deletion compiler/runtime/yk__process.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ size_t yk__windows_quote_argument(yk__sds argument, yk__sds *output,
if (NULL != output) { *output = yk__sdsempty(); }
yk__append(output, "\"");
for (size_t i = 0; i < input_length; ++i) {
unsigned NumberBackslashes = 0;
int NumberBackslashes = 0;
while (i < input_length && argument[i] == '\\') {
++i;
++NumberBackslashes;
Expand Down
23 changes: 12 additions & 11 deletions compiler/scripts/update_license.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,36 @@
# Note: libs - MIT license, runtime/3rd - various
# ==============================================================================================
# GPLv3:
#
#
# Yaksha - Programming Language.
# Copyright (C) 2020 - 2024 Bhathiya Perera
#
#
# This program is free software: you can redistribute it and/or modify it under the terms
# of the GNU General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License along with this program.
# If not, see https://www.gnu.org/licenses/.
#
#
# ==============================================================================================
# Additional Terms:
#
#
# Please note that any commercial use of the programming language's compiler source code
# (everything except compiler/runtime, compiler/libs and compiler/3rd) require a written agreement
# with author of the language (Bhathiya Perera).
#
#
# If you are using it for an open source project, please give credits.
# Your own project must use GPLv3 license with these additional terms.
#
#
# You may use programs written in Yaksha/YakshaLisp for any legal purpose
# (commercial, open-source, closed-source, etc) as long as it agrees
# to the licenses of linked runtime libraries (see compiler/runtime/README.md).
#
#
# ==============================================================================================
LICENSE = \
""" ==============================================================================================
Expand Down Expand Up @@ -100,9 +100,10 @@ def add_license(fp: str, ext):
with open(os.path.join(COMPILER_ROOT, fp), "r+", encoding="utf-8") as h:
text = h.read()
cmt = COMMENT[ext] + " "
license = os.linesep.join([cmt + x for x in LICENSE])
newline = "\n"
license_ = newline.join([cmt + x.rstrip() for x in LICENSE])
with open(os.path.join(COMPILER_ROOT, fp), "w+", encoding="utf-8") as h:
h.write(license + os.linesep + text)
h.write(license_ + newline + text)


def main():
Expand Down
754 changes: 753 additions & 1 deletion compiler/src/ast/ast.h

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions compiler/src/ast/codefiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@
#include <unordered_set>
#include <vector>
namespace yaksha {
struct directives {
// Flags
bool no_main_{false};
bool apply_native_define_{false};
bool no_libs_{false};
// Conditional directives
std::vector<directive_stmt *> include_paths_{};
std::vector<directive_stmt *> library_paths_{};
std::vector<directive_stmt *> libraries_{};
std::vector<directive_stmt *> compile_args_{};
std::vector<directive_stmt *> link_args_{};
std::vector<directive_stmt *> defines_{};
std::vector<directive_stmt *> c_files_{};
};
struct codefiles {
codefiles(std::filesystem::path &libs_path, errors::error_printer *ep);
~codefiles();
Expand All @@ -65,6 +79,7 @@ namespace yaksha {
ykdt_pool pool_;
yaksha_macros yaksha_macros_{};
entry_struct_func_compiler *esc_;
directives directives_{};

private:
file_data *parse_or_null(std::filesystem::path &file_name);
Expand Down
1 change: 1 addition & 0 deletions compiler/src/compiler/codegen_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ comp_result codegen_c::emit(codefiles *cf, gc_pool<token> *token_pool,
rf.insert(rf.end(), runtime_features.begin(), runtime_features.end());
std::sort(rf.begin(), rf.end());
std::stringstream c_code{};
// TODO deprecate runtimefeature
// Write the feature requirements
// ---
// Format: // YK --> no requirements
Expand Down
115 changes: 78 additions & 37 deletions compiler/src/compiler/def_class_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@
// ==============================================================================================
// def_class_visitor.cpp
#include "def_class_visitor.h"
#include "ast/codefiles.h"
#include "builtins/builtins.h"
#include "compiler_utils.h"
#include <regex>
using namespace yaksha;
def_class_visitor::def_class_visitor(builtins *builtins)
: builtins_(builtins){};
def_class_visitor::def_class_visitor(builtins *builtins, codefiles *cf)
: builtins_(builtins), cf_(cf){};
def_class_visitor::~def_class_visitor() = default;
void def_class_visitor::visit_assign_expr(assign_expr *obj) {}
void def_class_visitor::visit_binary_expr(binary_expr *obj) {}
Expand Down Expand Up @@ -286,40 +287,8 @@ void def_class_visitor::visit_union_stmt(union_stmt *obj) {}
void def_class_visitor::visit_directive_stmt(directive_stmt *obj) {
obj->hits_ = 1;// Always consider this to be used!
auto directive_type = obj->directive_type_->token_;
/* these must have no STR argument */
bool zero_arg_directive =
// (Global flag) No need to check for main()
directive_type == "no_main" ||// TODO
// (Global flag) If a function takes 'str' parameters, it is thrown as an error)
directive_type == "ban_str_params" ||// TODO
// (Global flag) Directly substitute '@nativedefine' or 'native constants'
directive_type == "apply_nativedefine";// TODO
/* ========================================================================= */
/* these must have the argument string, and it cannot be empty */
bool must_have_arg_directive =
// Write this raw code directly to output!
directive_type == "ccode" ||
// (Global) Include path -I <arg>
directive_type == "c_include_path" ||// TODO
// (Global) -L <arg>
directive_type == "c_lib_path" ||// TODO
// Write #include "arg"
directive_type == "c_include" ||
// Write #include <arg>
directive_type == "c_sys_include" ||
// Compile and link with this '.c' file's .o file, in addition to output code
// --> can also take, c_compile_arg, c_define parameters for that specific file
directive_type == "c_file" ||// TODO
// (Global) Link with this, -l<arg>, for example
directive_type == "c_lib" ||// TODO
// (Global) use this compilation argument for all code files
directive_type == "c_compile_arg" ||// TODO
// (Global) when all .o objects are linked together, use these arguments
directive_type == "c_link_arg" ||// TODO
// (Global) use these arguments for linking or compiling
directive_type == "c_compile_or_link_arg" ||// TODO
// (Global) define this when compiling. -D<arg>
directive_type == "c_define";// TODO
bool zero_arg_directive = has_zero_arg_directive(obj);
bool must_have_arg_directive = has_one_arg_directive(obj);
if (zero_arg_directive || must_have_arg_directive) {
if (zero_arg_directive && obj->directive_val_ != nullptr) {
error(obj->directive_val_,
Expand All @@ -334,5 +303,77 @@ void def_class_visitor::visit_directive_stmt(directive_stmt *obj) {
error(obj->directive_type_,
"Invalid directive. Only no_main, no_string and ccode are supported");
}
directives_.push_back(obj);
}
bool def_class_visitor::has_one_arg_directive(directive_stmt *obj) {
auto directive_type = obj->directive_type_->token_;
/* these must have the argument string, and it cannot be empty */
bool must_have_arg_directive = false;
// Write this raw code (unescaped) directly to output! 🟡
// Write #include "arg" 🟡
// Write #include <arg> 🟡
if (directive_type == "ccode" || directive_type == "c_include" ||
directive_type == "c_sys_include") {
must_have_arg_directive = true;
}
// (Global) Include path -I <arg> 🔴
if (directive_type == "c_include_path") {
must_have_arg_directive = true;
cf_->directives_.include_paths_.emplace_back(obj);
}
// (Global) Library path -L <arg> 🔴
if (directive_type == "c_lib_path") {
must_have_arg_directive = true;
cf_->directives_.library_paths_.emplace_back(obj);
}
// Compile and link with this '.c' file's .o file, in addition to output code
// --> can also take, c_compile_arg, c_define parameters for that specific file
// will support following parameter 🔴
// os 1,arch 1,c_define *,c_compile_arg *,inherit_compile_args
if (directive_type == "c_file") {
must_have_arg_directive = true;
cf_->directives_.c_files_.emplace_back(obj);
}
// (Global) Link with this, -l<arg>, for example 🔴
if (directive_type == "c_lib") {
must_have_arg_directive = true;
cf_->directives_.libraries_.emplace_back(obj);
}
// (Global) compilation argument for all code files 🔴
if (directive_type == "c_compile_arg") {
must_have_arg_directive = true;
cf_->directives_.compile_args_.emplace_back(obj);
}
// (Global) use this arg during link time 🔴
if (directive_type == "c_link_arg") {
must_have_arg_directive = true;
cf_->directives_.compile_args_.emplace_back(obj);
}
// (Global) use this define during compilation time of all .c files
// 🔴
if (directive_type == "c_define") {
must_have_arg_directive = true;
cf_->directives_.defines_.emplace_back(obj);
}
return must_have_arg_directive;
}
bool def_class_visitor::has_zero_arg_directive(directive_stmt *obj) {
auto directive_type = obj->directive_type_->token_;
/* these must have no STR argument */
bool zero_arg_directive = false;
// (Global flag) No need to check for main() 🔴
if (directive_type == "no_main") {
zero_arg_directive = true;
cf_->directives_.no_main_ = true;
}
// (Global flag) Directly substitute '@nativedefine' or 'native constants'
if (directive_type == "apply_nativedefine") {// 🔴
zero_arg_directive = true;
cf_->directives_.apply_native_define_ = true;
}
// (Global flag) no yaksha runtime / libs, 🔴
if (directive_type == "no_libs") {
zero_arg_directive = true;
cf_->directives_.no_libs_ = true;
}
return zero_arg_directive;
}
7 changes: 5 additions & 2 deletions compiler/src/compiler/def_class_visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ namespace yaksha {
*
* We also extract classes in this phase
*/
struct codefiles;
struct def_class_visitor : expr_visitor, stmt_visitor {
explicit def_class_visitor(builtins *builtins);
def_class_visitor(builtins *builtins, codefiles *cf);
~def_class_visitor() override;
void extract(const std::vector<stmt *> &statements);
void visit_assign_expr(assign_expr *obj) override;
Expand Down Expand Up @@ -112,15 +113,17 @@ namespace yaksha {
std::vector<std::string> global_native_const_names_{};
std::vector<parsing_error> errors_{};
std::unordered_set<std::string> runtime_features_{};
std::vector<directive_stmt *> directives_{};

private:
std::unordered_map<std::string, def_stmt *> functions_{};
std::unordered_map<std::string, class_stmt *> classes_{};
std::unordered_map<std::string, const_stmt *> global_consts_{};
std::unordered_map<std::string, nativeconst_stmt *> global_native_consts_{};
builtins *builtins_;
codefiles *cf_;
void error(token *tok, const std::string &message);
bool has_zero_arg_directive(directive_stmt *obj);
bool has_one_arg_directive(directive_stmt *obj);
};
}// namespace yaksha
#endif
2 changes: 1 addition & 1 deletion compiler/src/compiler/multifile_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ comp_result multifile_compiler::compile_all(codegen *code_generator) {
for (auto f : cf_->files_) {
LOG_COMP("file:" << f->filepath_.string());
auto builtins_obj = new builtins(&(cf_->pool_), &token_pool_);
f->data_->dsv_ = new def_class_visitor(builtins_obj);
f->data_->dsv_ = new def_class_visitor(builtins_obj, cf_);
f->data_->dsv_->extract(f->data_->parser_->stmts_);
LOG_COMP("dsv extract:" << f->filepath_.string());
if (!f->data_->dsv_->errors_.empty()) {
Expand Down
Loading

0 comments on commit 9c669c0

Please sign in to comment.