From 388134ea09283475bcf61ea33432c8861b469a3c Mon Sep 17 00:00:00 2001 From: Ehren Metcalfe Date: Wed, 28 Aug 2024 17:12:44 -0400 Subject: [PATCH] namespaces (TODO allow with class definitions), use for selfhost util functions --- ceto/codegen.py | 19 +++- ceto/semanticanalysis.py | 2 +- include/ceto_checked_array_access.cth | 36 ++++---- ...ked_array_access.donotedit.autogenerated.h | 12 ++- selfhost/ast.cth | 22 ++--- selfhost/ast.donotedit.autogenerated.h | 32 +++---- selfhost/evalable_repr.cth | 17 ++-- .../evalable_repr.donotedit.autogenerated.h | 22 +++-- selfhost/macro_expansion.cth | 2 +- .../macro_expansion.donotedit.autogenerated.h | 18 ++-- selfhost/range_utility.cth | 57 ++++++------ .../range_utility.donotedit.autogenerated.h | 59 +++++++------ selfhost/scope.cth | 4 +- selfhost/scope.donotedit.autogenerated.h | 8 +- selfhost/utility.cth | 87 +++++++++---------- selfhost/utility.donotedit.autogenerated.h | 13 +-- 16 files changed, 219 insertions(+), 191 deletions(-) diff --git a/ceto/codegen.py b/ceto/codegen.py index f8fd012c..3f84028c 100755 --- a/ceto/codegen.py +++ b/ceto/codegen.py @@ -2084,6 +2084,23 @@ def codegen_call(node: Call, cx: Scope): if func_name == "isinstance": cast_string = "(" + cast_string + " != nullptr)" return cast_string + elif func_name == "namespace": + if len(node.args) == 0: + raise CodeGenError("empty namespace args", node) + block = node.args[-1] + if not isinstance(block, Block): + raise CodeGenError("namespace last args must be a Block", node) + if len(node.args) > 2: + raise CodeGenError("too many namespace args", node) + if len(node.args) == 2: + name = node.args[0] + if not isinstance(name, (Identifier, ScopeResolution, AttributeAccess)): + raise CodeGenError("bad namespace name", node) + name_code = codegen_node(name, cx) + else: + name_code = "" + block_code = codegen_block(block, cx.enter_scope()) + return "namespace " + name_code + " {\n" + block_code + "\n}" elif func_name == "defmacro": return "\n" else: @@ -2735,7 +2752,7 @@ def codegen_node(node: Node, cx: Scope): raise CodeGenError("advanced slicing not supported yet") func_str = codegen_node(node.func, cx) idx_str = codegen_node(node.args[0], cx) - return "ceto_bounds_check(" + func_str + "," + idx_str + ")" + return "ceto::bounds_check(" + func_str + "," + idx_str + ")" #raise CodeGenError("Array accesses should have been lowered in a macro pass! You've probably written your own array[access] defmacro (it's buggy)", node) elif isinstance(node, BracedCall): if cx.lookup_class(node.func): diff --git a/ceto/semanticanalysis.py b/ceto/semanticanalysis.py index 0dd174f6..b905cedb 100644 --- a/ceto/semanticanalysis.py +++ b/ceto/semanticanalysis.py @@ -958,7 +958,7 @@ def on_macro_def(mcd: MacroDefinition, replacements): dll_options = f"-fPIC -shared -Wl,-soname,{dll_path}.so -ldl" if sys.platform == "darwin": dll_options = "-dynamiclib" - build_command = f"c++ -Wall -Wextra -std=c++20 {include_opts} {dll_options} -o {dll_path} {dll_cpp}" + build_command = f"c++ -Wall -Wextra -std=c++20 -O0 -g3 {include_opts} {dll_options} -o {dll_path} {dll_cpp}" print(build_command) try: diff --git a/include/ceto_checked_array_access.cth b/include/ceto_checked_array_access.cth index a99a1a6c..9afa0db3 100644 --- a/include/ceto_checked_array_access.cth +++ b/include/ceto_checked_array_access.cth @@ -1,32 +1,34 @@ include include +namespace (ceto: -def (ceto_bounds_check, arr: mut:auto:ref:ref, index: mut:size_t: - if (index >= std.size(arr): - std.cerr << "terminating on out of bounds access" - std.terminate() - ) + def (bounds_check, arr: mut:auto:ref:ref, index: mut:size_t: + if (index >= std.size(arr): + std.cerr << "terminating on out of bounds access" + std.terminate() + ) - return std.forward(arr).unsafe_at(std.forward(index)); -) : decltype(auto):requires:requires(std.size(arr)) + return std.forward(arr).unsafe_at(std.forward(index)); + ) : decltype(auto):requires:requires(std.size(arr)) -def (ceto_bounds_check, o: mut:auto:ref:ref, index: mut:auto:ref:ref: - return std.forward(o).unsafe_at(std.forward(index)); -) : decltype(auto):requires:not std.is_integral_v> + def (bounds_check, o: mut:auto:ref:ref, index: mut:auto:ref:ref: + return std.forward(o).unsafe_at(std.forward(index)); + ) : decltype(auto):requires:not std.is_integral_v> -# from https://stackoverflow.com/questions/69785562/c-map-and-unordered-map-template-parameter-check-for-common-behavior-using-c/69869007#69869007 -ceto_is_map_type: template:concept = std.same_as> + # from https://stackoverflow.com/questions/69785562/c-map-and-unordered-map-template-parameter-check-for-common-behavior-using-c/69869007#69869007 + is_map_type: template:concept = std.same_as> -def (ceto_bounds_check, m: mut:auto:ref:ref, key: mut:auto:ref:ref: - return std.forward(m).unsafe_at(std.forward(key)); -) : decltype(auto):requires:std.is_integral_v> and ceto_is_map_type> + def (bounds_check, m: mut:auto:ref:ref, key: mut:auto:ref:ref: + return std.forward(m).unsafe_at(std.forward(key)); + ) : decltype(auto):requires:std.is_integral_v> and is_map_type> +) -# something wacky with current 'decltype_str' ArrayAccess handling (this still needs to be a late transformation in codegen.py) +# TODO something wacky with current 'decltype_str' ArrayAccess handling (or rather the handling of bounds_check with a decltype(auto) return type in decltype_str). This needs to be a late transformation in codegen.py for now. #defmacro (array[index], array, index: # if (array.name() == "lambda": # # not actually an array access (general syntax ftl) # return None # ) -# return quote(ceto_bounds_check(unquote(array), unquote(index))) +# return quote(ceto.bounds_check(unquote(array), unquote(index))) #) diff --git a/include/ceto_checked_array_access.donotedit.autogenerated.h b/include/ceto_checked_array_access.donotedit.autogenerated.h index ca71363b..bc866e89 100644 --- a/include/ceto_checked_array_access.donotedit.autogenerated.h +++ b/include/ceto_checked_array_access.donotedit.autogenerated.h @@ -14,12 +14,14 @@ #include "ceto.h" +#include "ceto_checked_array_access.donotedit.autogenerated.h" #include ; #include ; - inline auto ceto_bounds_check( auto && arr, size_t index) -> decltype(auto) requires (requires () { std::size(arr); +namespace ceto { + inline auto bounds_check( auto && arr, size_t index) -> decltype(auto) requires (requires () { std::size(arr); }) { if (index >= std::size(arr)) { std::cerr << "terminating on out of bounds access"; @@ -28,12 +30,14 @@ return std::forward(arr)[std::forward(index)]; } - inline auto ceto_bounds_check( auto && o, auto && index) -> decltype(auto) requires (!std::is_integral_v>) { + inline auto bounds_check( auto && o, auto && index) -> decltype(auto) requires (!std::is_integral_v>) { return std::forward(o)[std::forward(index)]; } -template concept ceto_is_map_type = std::same_as>; - inline auto ceto_bounds_check( auto && m, auto && key) -> decltype(auto) requires ((std::is_integral_v> && ceto_is_map_type>)) { + template concept is_map_type = std::same_as>; + inline auto bounds_check( auto && m, auto && key) -> decltype(auto) requires ((std::is_integral_v> && is_map_type>)) { return std::forward(m)[std::forward(key)]; } + +}; diff --git a/selfhost/ast.cth b/selfhost/ast.cth index cfd8ad41..759aec42 100755 --- a/selfhost/ast.cth +++ b/selfhost/ast.cth @@ -43,12 +43,12 @@ class (Node: _parent: Node:weak = {} def (classname: virtual: - return typeid_name(*this) + return ceto.util.typeid_name(*this) ) : std.string def (repr: virtual: classname = self.classname() - csv = join(self.args, lambda(a, a.repr()), ", ") + csv = ceto.util.join(self.args, lambda(a, a.repr()), ", ") return classname + "(" + self.func.repr() + ")([" + csv + "])" ) : std.string @@ -94,7 +94,7 @@ class (Node: return False ) - for (i in range(self.args.size()): + for (i in ceto.util.range(self.args.size()): if (not self.args[i].equals(other.args[i]): return False ) @@ -280,7 +280,7 @@ class (Assign(BinOp): class (NamedParameter(Assign): def (repr: override: - return "NamedParameter("s + join(self.args, lambda(a, a.repr()), ", ") + ")" + return "NamedParameter("s + ceto.util.join(self.args, lambda(a, a.repr()), ", ") + ")" ) : std.string def (accept: override, visitor: Visitor:mut:ref: @@ -353,7 +353,7 @@ class (Call(Node): is_one_liner_if = false def (repr: override: - csv = join(self.args, lambda (a, a.repr()), ", ") + csv = ceto.util.join(self.args, lambda (a, a.repr()), ", ") return self.func.repr() + "(" + csv + ")" ) : std.string @@ -369,7 +369,7 @@ class (Call(Node): class (ArrayAccess(Node): def (repr: override: - csv = join(self.args, lambda (a, a.repr()), ", ") + csv = ceto.util.join(self.args, lambda (a, a.repr()), ", ") return self.func.repr() + "[" + csv + "]" ) : std.string @@ -385,7 +385,7 @@ class (ArrayAccess(Node): class (BracedCall(Node): def (repr: override: - csv = join(self.args, lambda (a, a.repr()), ", ") + csv = ceto.util.join(self.args, lambda (a, a.repr()), ", ") return self.func.repr() + "{" + csv + "}" ) : std.string @@ -401,7 +401,7 @@ class (BracedCall(Node): class (Template(Node): def (repr: override: - csv = join(self.args, lambda (a, a.repr()), ", ") + csv = ceto.util.join(self.args, lambda (a, a.repr()), ", ") return self.func.repr() + "<" + csv + ">" ) : std.string @@ -596,7 +596,7 @@ class (ListLike_(Node): def (repr: override: classname = self.classname() - return classname + "(" + join(self.args, lambda (a, a.repr()), ", ") + ")" + return classname + "(" + ceto.util.join(self.args, lambda (a, a.repr()), ", ") + ")" ) : std.string def (accept: override, visitor: Visitor:mut:ref: @@ -673,7 +673,7 @@ class (RedundantParens(Node): def (repr: override: classname = self.classname() - return classname + "(" + join(self.args, lambda (a, a.repr()), ", ") + ")" + return classname + "(" + ceto.util.join(self.args, lambda (a, a.repr()), ", ") + ")" ) : std.string def (accept: override, visitor: Visitor:mut:ref: @@ -693,7 +693,7 @@ class (InfixWrapper_(Node): def (repr: override: classname = self.classname() - return classname + "(" + join(self.args, lambda (a, a.repr()), ", ") + ")" + return classname + "(" + ceto.util.join(self.args, lambda (a, a.repr()), ", ") + ")" ) : std.string def (accept: override, visitor: Visitor:mut:ref: diff --git a/selfhost/ast.donotedit.autogenerated.h b/selfhost/ast.donotedit.autogenerated.h index 5c6963d1..a3184fb2 100644 --- a/selfhost/ast.donotedit.autogenerated.h +++ b/selfhost/ast.donotedit.autogenerated.h @@ -64,12 +64,12 @@ struct Node : public ceto::shared_object, public std::enable_shared_from_this _parent = {}; virtual inline auto classname() const -> std::string { - return typeid_name((*this)); + return ceto::util::typeid_name((*this)); } virtual inline auto repr() const -> std::string { const auto classname = this -> classname(); - const auto csv = join(this -> args, [](const auto &a) { + const auto csv = ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", "); return (((((classname + "(") + (*ceto::mad(this -> func)).repr()) + ")([") + csv) + "])"); @@ -123,8 +123,8 @@ struct Node : public ceto::shared_object, public std::enable_shared_from_this args)).size() != (*ceto::mad((*ceto::mad(other)).args)).size()) { return false; } - for(const auto& i : range((*ceto::mad(this -> args)).size())) { - if (!(*ceto::mad(ceto_bounds_check(this -> args,i))).equals(ceto_bounds_check((*ceto::mad(other)).args,i))) { + for(const auto& i : ceto::util::range((*ceto::mad(this -> args)).size())) { + if (!(*ceto::mad(ceto::bounds_check(this -> args,i))).equals(ceto::bounds_check((*ceto::mad(other)).args,i))) { return false; } } @@ -155,7 +155,7 @@ struct UnOp : public Node { std::string op; inline auto repr() const -> std::string override { - return ((((std::string {"("} + (this -> op)) + " ") + (*ceto::mad(ceto_bounds_check(this -> args,0))).repr()) + ")"); + return ((((std::string {"("} + (this -> op)) + " ") + (*ceto::mad(ceto::bounds_check(this -> args,0))).repr()) + ")"); } inline auto accept( Visitor & visitor) const -> void override { @@ -179,7 +179,7 @@ struct LeftAssociativeUnOp : public Node { std::string op; inline auto repr() const -> std::string override { - return (((("(" + (*ceto::mad(ceto_bounds_check(this -> args,0))).repr()) + " ") + (this -> op)) + ")"); + return (((("(" + (*ceto::mad(ceto::bounds_check(this -> args,0))).repr()) + " ") + (this -> op)) + ")"); } inline auto accept( Visitor & visitor) const -> void override { @@ -203,11 +203,11 @@ struct BinOp : public Node { std::string op; inline auto lhs() const -> auto { - return ceto_bounds_check(this -> args,0); + return ceto::bounds_check(this -> args,0); } inline auto rhs() const -> auto { - return ceto_bounds_check(this -> args,1); + return ceto::bounds_check(this -> args,1); } inline auto repr() const -> std::string override { @@ -342,7 +342,7 @@ struct NamedParameter : public Assign { using Assign::Assign; inline auto repr() const -> std::string override { - return ((std::string {"NamedParameter("} + join(this -> args, [](const auto &a) { + return ((std::string {"NamedParameter("} + ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", ")) + ")"); } @@ -431,7 +431,7 @@ using Node::Node; decltype(false) is_one_liner_if = false; inline auto repr() const -> std::string override { - const auto csv = join(this -> args, [](const auto &a) { + const auto csv = ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", "); return ((((*ceto::mad(this -> func)).repr() + "(") + csv) + ")"); @@ -453,7 +453,7 @@ struct ArrayAccess : public Node { using Node::Node; inline auto repr() const -> std::string override { - const auto csv = join(this -> args, [](const auto &a) { + const auto csv = ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", "); return ((((*ceto::mad(this -> func)).repr() + "[") + csv) + "]"); @@ -475,7 +475,7 @@ struct BracedCall : public Node { using Node::Node; inline auto repr() const -> std::string override { - const auto csv = join(this -> args, [](const auto &a) { + const auto csv = ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", "); return ((((*ceto::mad(this -> func)).repr() + "{") + csv) + "}"); @@ -497,7 +497,7 @@ struct Template : public Node { using Node::Node; inline auto repr() const -> std::string override { - const auto csv = join(this -> args, [](const auto &a) { + const auto csv = ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", "); return ((((*ceto::mad(this -> func)).repr() + "<") + csv) + ">"); @@ -728,7 +728,7 @@ struct ListLike_ : public Node { inline auto repr() const -> std::string override { const auto classname = this -> classname(); - return (((classname + "(") + join(this -> args, [](const auto &a) { + return (((classname + "(") + ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", ")) + ")"); } @@ -830,7 +830,7 @@ struct RedundantParens : public Node { inline auto repr() const -> std::string override { const auto classname = this -> classname(); - return (((classname + "(") + join(this -> args, [](const auto &a) { + return (((classname + "(") + ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", ")) + ")"); } @@ -855,7 +855,7 @@ struct InfixWrapper_ : public Node { inline auto repr() const -> std::string override { const auto classname = this -> classname(); - return (((classname + "(") + join(this -> args, [](const auto &a) { + return (((classname + "(") + ceto::util::join(this -> args, [](const auto &a) { if constexpr (!std::is_void_v) { return (*ceto::mad(a)).repr(); } else { static_cast((*ceto::mad(a)).repr()); }; }, ", ")) + ")"); } diff --git a/selfhost/evalable_repr.cth b/selfhost/evalable_repr.cth index d5a94fb7..7b291ab5 100644 --- a/selfhost/evalable_repr.cth +++ b/selfhost/evalable_repr.cth @@ -1,6 +1,5 @@ include (visitor) include (ast) -include (utility) struct (EvalableAstReprVisitor(BaseVisitor): @@ -21,7 +20,7 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: Node.class: - self.repr += std.string(typeid_name(node)) + "(" + self.repr += node.classname() + "(" if (node.func: node.func.accept(*this) @@ -41,7 +40,7 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: UnOp.class: - self.repr += std.string(typeid_name(node)) + '("' + node.op + '", [' + self.repr += node.classname() + '("' + node.op + '", [' node.args[0].accept(*this) self.repr += "]"s + if (self.ceto_evalable: ": Node" else: "") + ", " self.generate_loc(node) @@ -49,7 +48,7 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: LeftAssociativeUnOp.class: - self.repr += std.string(typeid_name(node)) + '("' + node.op + '", [' + self.repr += node.classname() + '("' + node.op + '", [' node.args[0].accept(*this) self.repr += "]"s + if (self.ceto_evalable: ": Node" else: "") + ", " self.generate_loc(node) @@ -57,7 +56,7 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: BinOp.class: - self.repr += std.string(typeid_name(node)) + '("' + node.op + '", [' + self.repr += node.classname() + '("' + node.op + '", [' for (arg in node.args: arg.accept(*this) self.repr += ", " @@ -68,14 +67,14 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: Identifier.class: - self.repr += std.string(typeid_name(node)) + '("' + node.repr() + '"' + self.repr += node.classname() + '("' + node.repr() + '"' self.repr += ", " self.generate_loc(node) self.repr += ")" ) def (visit: override:mut, node: StringLiteral.class: - self.repr += std.string(typeid_name(node)) + "(" + node.escaped() + ", " + self.repr += node.classname() + "(" + node.escaped() + ", " if (node.prefix: node.prefix.accept(*this) @@ -95,7 +94,7 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: IntegerLiteral.class: - self.repr += std.string(typeid_name(node)) + '("' + node.integer_string + '", ' + self.repr += node.classname() + '("' + node.integer_string + '", ' if (node.suffix: node.suffix.accept(*this) else: @@ -107,7 +106,7 @@ struct (EvalableAstReprVisitor(BaseVisitor): ) def (visit: override:mut, node: FloatLiteral.class: - self.repr += std.string(typeid_name(node)) + '("' + node.float_string + '", ' + self.repr += node.classname() + '("' + node.float_string + '", ' if (node.suffix: node.suffix.accept(*this) else: diff --git a/selfhost/evalable_repr.donotedit.autogenerated.h b/selfhost/evalable_repr.donotedit.autogenerated.h index 8d48b655..feecec7d 100644 --- a/selfhost/evalable_repr.donotedit.autogenerated.h +++ b/selfhost/evalable_repr.donotedit.autogenerated.h @@ -20,8 +20,6 @@ ; #include "ast.donotedit.autogenerated.h" ; -#include "utility.donotedit.autogenerated.h" -; struct EvalableAstReprVisitor : public BaseVisitor { bool preserve_source_loc; @@ -40,7 +38,7 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const Node& node) -> void override { - (this -> repr) += (std::string(typeid_name(node)) + "("); + (this -> repr) += ((*ceto::mad(node)).classname() + "("); if ((*ceto::mad(node)).func) { (*ceto::mad((*ceto::mad(node)).func)).accept((*this)); (this -> repr) += ", "; @@ -61,8 +59,8 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const UnOp& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(\"") + (*ceto::mad(node)).op) + "\", ["); - (*ceto::mad(ceto_bounds_check((*ceto::mad(node)).args,0))).accept((*this)); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(\"") + (*ceto::mad(node)).op) + "\", ["); + (*ceto::mad(ceto::bounds_check((*ceto::mad(node)).args,0))).accept((*this)); (this -> repr) += ((std::string {"]"} + [&]() {if (this -> ceto_evalable) { return ": Node"; } else { @@ -74,8 +72,8 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const LeftAssociativeUnOp& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(\"") + (*ceto::mad(node)).op) + "\", ["); - (*ceto::mad(ceto_bounds_check((*ceto::mad(node)).args,0))).accept((*this)); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(\"") + (*ceto::mad(node)).op) + "\", ["); + (*ceto::mad(ceto::bounds_check((*ceto::mad(node)).args,0))).accept((*this)); (this -> repr) += ((std::string {"]"} + [&]() {if (this -> ceto_evalable) { return ": Node"; } else { @@ -87,7 +85,7 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const BinOp& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(\"") + (*ceto::mad(node)).op) + "\", ["); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(\"") + (*ceto::mad(node)).op) + "\", ["); for(const auto& arg : (*ceto::mad(node)).args) { (*ceto::mad(arg)).accept((*this)); (this -> repr) += ", "; @@ -103,14 +101,14 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const Identifier& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(\"") + (*ceto::mad(node)).repr()) + "\""); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(\"") + (*ceto::mad(node)).repr()) + "\""); (this -> repr) += ", "; this -> generate_loc(node); (this -> repr) += ")"; } inline auto visit(const StringLiteral& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(") + (*ceto::mad(node)).escaped()) + ", "); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(") + (*ceto::mad(node)).escaped()) + ", "); if ((*ceto::mad(node)).prefix) { (*ceto::mad((*ceto::mad(node)).prefix)).accept((*this)); } else { @@ -128,7 +126,7 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const IntegerLiteral& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(\"") + (*ceto::mad(node)).integer_string) + "\", "); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(\"") + (*ceto::mad(node)).integer_string) + "\", "); if ((*ceto::mad(node)).suffix) { (*ceto::mad((*ceto::mad(node)).suffix)).accept((*this)); } else { @@ -140,7 +138,7 @@ auto generate_loc(const T1& node) -> void { } inline auto visit(const FloatLiteral& node) -> void override { - (this -> repr) += (((std::string(typeid_name(node)) + "(\"") + (*ceto::mad(node)).float_string) + "\", "); + (this -> repr) += ((((*ceto::mad(node)).classname() + "(\"") + (*ceto::mad(node)).float_string) + "\", "); if ((*ceto::mad(node)).suffix) { (*ceto::mad((*ceto::mad(node)).suffix)).accept((*this)); } else { diff --git a/selfhost/macro_expansion.cth b/selfhost/macro_expansion.cth index 49c79a60..1c1356e3 100644 --- a/selfhost/macro_expansion.cth +++ b/selfhost/macro_expansion.cth @@ -232,7 +232,7 @@ struct (MacroDefinitionVisitor(BaseVisitor): def (expand: mut, node: Node: scope: mut:auto:const:ptr = (&self.current_scope)->get() while (scope: - for (definition in reversed(scope->macro_definitions): + for (definition in ceto.util.reversed(scope->macro_definitions): match = macro_matches(node, definition.pattern_node, definition.parameters) if (match: std.cout << "found match\n" diff --git a/selfhost/macro_expansion.donotedit.autogenerated.h b/selfhost/macro_expansion.donotedit.autogenerated.h index 5220d1c6..bcff3b67 100644 --- a/selfhost/macro_expansion.donotedit.autogenerated.h +++ b/selfhost/macro_expansion.donotedit.autogenerated.h @@ -156,15 +156,15 @@ struct MacroScope : public ceto::object { const auto param_name = (search -> first); const auto matched_param = (search -> second); if ((std::dynamic_pointer_cast(matched_param) != nullptr)) { - if (const auto list_param = std::dynamic_pointer_cast(ceto_bounds_check((*ceto::mad(matched_param)).args,1))) { + if (const auto list_param = std::dynamic_pointer_cast(ceto::bounds_check((*ceto::mad(matched_param)).args,1))) { if ((*ceto::mad((*ceto::mad(list_param)).args)).size() != 1) { throw SemanticAnalysisError{"bad ListLiteral args in macro param"}; } - const auto wildcard_list_type = ceto_bounds_check((*ceto::mad(list_param)).args,0); + const auto wildcard_list_type = ceto::bounds_check((*ceto::mad(list_param)).args,0); if (!(std::dynamic_pointer_cast(wildcard_list_type) != nullptr)) { throw SemanticAnalysisError{"bad ListLiteral arg type in macro param"}; } - const auto wildcard_list_name = ceto_bounds_check((*ceto::mad(matched_param)).args,0); + const auto wildcard_list_name = ceto::bounds_check((*ceto::mad(matched_param)).args,0); if (!(std::dynamic_pointer_cast(wildcard_list_name) != nullptr)) { throw SemanticAnalysisError{"arg of type ListLiteral must be an identifier"}; } @@ -179,7 +179,7 @@ struct MacroScope : public ceto::object { } arg_iterator += 1; } - ceto_bounds_check(submatches,param_name) = std::make_shared(wildcard_list_matches); + ceto::bounds_check(submatches,param_name) = std::make_shared(wildcard_list_matches); pattern_iterator += 1; if (pattern_iterator == (*ceto::mad((*ceto::mad(pattern)).args)).end()) { if (arg_iterator != (*ceto::mad((*ceto::mad(node)).args)).end()) { @@ -235,14 +235,14 @@ struct MacroDefinitionVisitor : public BaseVisitor { inline auto expand(const std::shared_ptr& node) -> auto { auto const * scope { (&(this -> current_scope)) -> get() } ; - while (scope) { for(const auto& definition : reversed(scope -> macro_definitions)) { + while (scope) { for(const auto& definition : ceto::util::reversed(scope -> macro_definitions)) { const auto match = macro_matches(node, (*ceto::mad(definition)).pattern_node, (*ceto::mad(definition)).parameters); if (match) { std::cout << "found match\n"; const auto replacement = call_macro_impl(definition, (*ceto::mad_smartptr(match)).value()); if (replacement && (replacement != node)) { ((((std::cout << "found replacement for ") << (*ceto::mad(node)).repr()) << ": ") << (*ceto::mad(replacement)).repr()) << std::endl; - ceto_bounds_check(this -> replacements,node) = replacement; + ceto::bounds_check(this -> replacements,node) = replacement; (*ceto::mad(replacement)).accept((*this)); return true; } @@ -280,7 +280,7 @@ struct MacroDefinitionVisitor : public BaseVisitor { if ((*ceto::mad((*ceto::mad(node)).args)).size() < 2) { throw SemanticAnalysisError{"bad defmacro args"}; } - const auto pattern = ceto_bounds_check((*ceto::mad(node)).args,0); + const auto pattern = ceto::bounds_check((*ceto::mad(node)).args,0); if (!(std::dynamic_pointer_cast((*ceto::mad((*ceto::mad(node)).args)).back()) != nullptr)) { throw SemanticAnalysisError{"last defmacro arg must be a Block"}; } @@ -296,10 +296,10 @@ struct MacroDefinitionVisitor : public BaseVisitor { return (*ceto::mad_smartptr((*ceto::mad(arg)).name())).value(); } else if (!(std::dynamic_pointer_cast(arg) != nullptr)) { throw SemanticAnalysisError{"bad defmacro param type"}; - } else if (!(std::dynamic_pointer_cast(ceto_bounds_check((*ceto::mad(arg)).args,0)) != nullptr)) { + } else if (!(std::dynamic_pointer_cast(ceto::bounds_check((*ceto::mad(arg)).args,0)) != nullptr)) { throw SemanticAnalysisError{"bad typed defmacro param"}; } else { - return (*ceto::mad_smartptr((*ceto::mad(ceto_bounds_check((*ceto::mad(arg)).args,0))).name())).value(); + return (*ceto::mad_smartptr((*ceto::mad(ceto::bounds_check((*ceto::mad(arg)).args,0))).name())).value(); }}() ; const auto i = (*ceto::mad(parameters)).find(name); diff --git a/selfhost/range_utility.cth b/selfhost/range_utility.cth index 9967adcd..4f5f0cae 100644 --- a/selfhost/range_utility.cth +++ b/selfhost/range_utility.cth @@ -2,38 +2,41 @@ include include include -# poor ranges supprt with current apple clang (15). This is good enough for internal use: +namespace (ceto.util: -if (defined(__clang__) and __clang_major__ < 16: + if (defined(__clang__) and __clang_major__ < 16: + # poor ranges supprt with current apple clang (15). This is good enough for internal use: - def (range, start: size_t, stop: size_t: - r: mut = std.vector (stop - start); - std.iota(r.begin(), r.end(), start) - return r - ) : std.vector + def (range, start: size_t, stop: size_t: + r: mut = std.vector (stop - start); + std.iota(r.begin(), r.end(), start) + return r + ) : std.vector - def (range, stop: size_t: - return range(0u, stop) - ) + def (range, stop: size_t: + return range(0u, stop) + ) - def (reversed: template, container: const:std.vector:ref: - rev = std.vector (container.rbegin(), container.rend()) - return rev - ) + def (reversed: template, container: const:std.vector:ref: + rev = std.vector (container.rbegin(), container.rend()) + return rev + ) -else: + else: - def (range: template, args: mut:Args:rref:...: - if ((sizeof...)(Args) == 1: - zero : typename:std.tuple_element<0, std.tuple>::type = 0 - return std.ranges.iota_view(zero, std.forward(args)...) - else: - return std.ranges.iota_view(std.forward(args)...) - ) : constexpr - ) : decltype(auto) + def (range: template, args: mut:Args:rref:...: + if ((sizeof...)(Args) == 1: + zero : typename:std.tuple_element<0, std.tuple>::type = 0 + return std.ranges.iota_view(zero, std.forward(args)...) + else: + return std.ranges.iota_view(std.forward(args)...) + ) : constexpr + ) : decltype(auto) - def (reversed: template, args: mut:Args:rref:...: - return std.views.reverse(std.forward(args)...) - ) : decltype(auto) + def (reversed: template, args: mut:Args:rref:...: + return std.views.reverse(std.forward(args)...) + ) : decltype(auto) -) : preprocessor + ) : preprocessor + +) diff --git a/selfhost/range_utility.donotedit.autogenerated.h b/selfhost/range_utility.donotedit.autogenerated.h index e7e471f8..569c4ee8 100644 --- a/selfhost/range_utility.donotedit.autogenerated.h +++ b/selfhost/range_utility.donotedit.autogenerated.h @@ -22,35 +22,38 @@ ; #include ; -#if defined(__clang__) && (__clang_major__ < 16) - inline auto range(const size_t start, const size_t stop) -> std::vector { - auto r { std::vector(stop - start) } ; - std::iota((*ceto::mad(r)).begin(), (*ceto::mad(r)).end(), start); - return r; - } - - inline auto range(const size_t stop) -> auto { - return range(0u, stop); - } - - template inline auto reversed( const std::vector & container) -> auto { - const auto rev = std::vector((*ceto::mad(container)).rbegin(), (*ceto::mad(container)).rend()); - return rev; - } - -#else - template inline auto range( Args && ... args) -> decltype(auto) { - if constexpr (sizeof...(Args) == 1) { - const typename std::tuple_element<0,std::tuple> :: type zero { 0 } ; static_assert(std::is_convertible_v); - return std::ranges::iota_view(zero, std::forward(args)...); - } else { - return std::ranges::iota_view(std::forward(args)...); +namespace ceto::util { + #if defined(__clang__) && (__clang_major__ < 16) + inline auto range(const size_t start, const size_t stop) -> std::vector { + auto r { std::vector(stop - start) } ; + std::iota((*ceto::mad(r)).begin(), (*ceto::mad(r)).end(), start); + return r; } - } - template inline auto reversed( Args && ... args) -> decltype(auto) { - return std::views::reverse(std::forward(args)...); - } + inline auto range(const size_t stop) -> auto { + return range(0u, stop); + } + + template inline auto reversed( const std::vector & container) -> auto { + const auto rev = std::vector((*ceto::mad(container)).rbegin(), (*ceto::mad(container)).rend()); + return rev; + } + + #else + template inline auto range( Args && ... args) -> decltype(auto) { + if constexpr (sizeof...(Args) == 1) { + const typename std::tuple_element<0,std::tuple> :: type zero { 0 } ; static_assert(std::is_convertible_v); + return std::ranges::iota_view(zero, std::forward(args)...); + } else { + return std::ranges::iota_view(std::forward(args)...); + } + } + + template inline auto reversed( Args && ... args) -> decltype(auto) { + return std::views::reverse(std::forward(args)...); + } + + #endif -#endif +}; diff --git a/selfhost/scope.cth b/selfhost/scope.cth index 3fb7f31d..fb64e736 100644 --- a/selfhost/scope.cth +++ b/selfhost/scope.cth @@ -29,7 +29,7 @@ class (ClassDefinition: ) def (class_name: virtual: - return typeid_name(*this) + return ceto.util.typeid_name(*this) ) : std.string def (destruct: virtual: @@ -52,7 +52,7 @@ class (VariableDefinition: ) def (class_name: virtual: - return typeid_name(*this) + return ceto.util.typeid_name(*this) ) : std.string def (destruct: virtual: diff --git a/selfhost/scope.donotedit.autogenerated.h b/selfhost/scope.donotedit.autogenerated.h index fe42932e..ea260d9b 100644 --- a/selfhost/scope.donotedit.autogenerated.h +++ b/selfhost/scope.donotedit.autogenerated.h @@ -43,7 +43,7 @@ struct ClassDefinition : public ceto::shared_object, public std::enable_shared_f } virtual inline auto class_name() const -> std::string { - return typeid_name((*this)); + return ceto::util::typeid_name((*this)); } virtual ~ClassDefinition() { @@ -74,7 +74,7 @@ struct VariableDefinition : public ceto::shared_object, public std::enable_share } virtual inline auto class_name() const -> std::string { - return typeid_name((*this)); + return ceto::util::typeid_name((*this)); } virtual ~VariableDefinition() { @@ -191,7 +191,7 @@ struct Scope : public ceto::shared_object, public std::enable_shared_from_this& interface_method_def_node) -> void { - (*ceto::mad(ceto_bounds_check(this -> interfaces,interface_name))).push_back(interface_method_def_node); + (*ceto::mad(ceto::bounds_check(this -> interfaces,interface_name))).push_back(interface_method_def_node); } inline auto add_class_definition(const std::shared_ptr& class_definition) -> void { @@ -255,7 +255,7 @@ struct Scope : public ceto::shared_object, public std::enable_shared_from_this find_defs(var_node, find_all); return [&]() {if ((*ceto::mad(found)).size() > 0) { - return ceto_bounds_check(found,0); + return ceto::bounds_check(found,0); } else { const std::shared_ptr none_result = nullptr; static_assert(ceto::is_non_aggregate_init_and_if_convertible_then_non_narrowing_v>); return none_result; diff --git a/selfhost/utility.cth b/selfhost/utility.cth index 756be3e5..12e15a85 100644 --- a/selfhost/utility.cth +++ b/selfhost/utility.cth @@ -2,7 +2,6 @@ include include include - if (_MSC_VER: cpp' #define CETO_EXPORT __declspec(dllexport) @@ -14,60 +13,60 @@ else: ' ): preprocessor +namespace (ceto.util: -def (join, v, to_string, sep=""s: - if (v.empty(): - return ""s + def (join, v, to_string, sep=""s: + if (v.empty(): + return ""s + ) + return std.accumulate(v.cbegin() + 1, v.cend(), to_string(v[0]), + lambda[&to_string, &sep] (a, el, a + sep + to_string(el))) ) - return std.accumulate(v.cbegin() + 1, v.cend(), to_string(v[0]), - lambda[&to_string, &sep] (a, el, a + sep + to_string(el))) -) + def (string_replace, source: std.string, from: std.string, to: std.string: + # Ingmar: https://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string/29752943#29752943 -# User Ingmar -# https://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string/29752943#29752943 -def (string_replace, source: std.string, from: std.string, to: std.string: - new_string : mut = std.string() - new_string.reserve(source.length()) # avoids a few memory allocations + new_string: mut = std.string() + new_string.reserve(source.length()) # avoids a few memory allocations - last_pos : mut:std.string.size_type = 0 # TODO just string.size_type should also generate std::string::size_type - find_pos : mut:std.string.size_type = 0 + last_pos: mut:std.string.size_type = 0 + find_pos: mut:std.string.size_type = 0 - while (std.string.npos != (find_pos = source.find(from, last_pos)): - new_string.append(source, last_pos, find_pos - last_pos) - new_string += to - last_pos = find_pos + from.length() - ) - - # better than new_string += source.substr(last_pos) to avoid creating temporary string [as substr() does]. – User tav - new_string.append(source, last_pos, source.length() - last_pos) + while (std.string.npos != (find_pos = source.find(from, last_pos)): + new_string.append(source, last_pos, find_pos - last_pos) + new_string += to + last_pos = find_pos + from.length() + ) - # clang and g++ -O3 produce less code returning by value than taking source by mut:ref as in answer url - return new_string -) + # better than new_string += source.substr(last_pos) to avoid creating temporary string [as substr() does]. – User tav + new_string.append(source, last_pos, source.length() - last_pos) + # clang and g++ -O3 produce less code returning by value than taking source by mut:ref as in answer url + return new_string + ) -def (contains, container, element: const:typename:std.remove_reference_t::value_type:ref: - return std.find(container.begin(), container.end(), element) != container.end() -) + def (contains, container, element: const:typename:std.remove_reference_t::value_type:ref: + return std.find(container.begin(), container.end(), element) != container.end() + ) -def (typeid_name, object: - if (_MSC_VER: - # already demangled: - name = typeid(object).name() + def (typeid_name, object: + if (_MSC_VER: + # already demangled: + name = typeid(object).name() - # remove 'struct ' prefix (another annoyance from msvc due to using 'struct' in C++ for 'class' in ceto): - std.literals: using:namespace - prefix = "struct "sv + # remove 'struct ' prefix (another annoyance from msvc due to using 'struct' in C++ for 'class' in ceto): + std.literals: using:namespace + prefix = "struct "sv - name_view = std.string_view(name) + name_view = std.string_view(name) - if (name_view.starts_with(prefix): - return name_view.substr(prefix.size()).data() - ) + if (name_view.starts_with(prefix): + return name_view.substr(prefix.size()).data() + ) - return name - else: - return abi.__cxa_demangle(typeid(object).name(), 0, 0, 0) - ) : preprocessor -) \ No newline at end of file + return name + else: + return abi.__cxa_demangle(typeid(object).name(), 0, 0, 0) + ) : preprocessor + ) +) diff --git a/selfhost/utility.donotedit.autogenerated.h b/selfhost/utility.donotedit.autogenerated.h index 264a66c2..25443416 100644 --- a/selfhost/utility.donotedit.autogenerated.h +++ b/selfhost/utility.donotedit.autogenerated.h @@ -34,17 +34,18 @@ ; #endif - template +namespace ceto::util { + template auto join(const T1& v, const T2& to_string, const decltype(std::string {""})& sep = std::string {""}) -> auto { if ((*ceto::mad(v)).empty()) { return std::string {""}; } - return std::accumulate((*ceto::mad(v)).cbegin() + 1, (*ceto::mad(v)).cend(), to_string(ceto_bounds_check(v,0)), [&to_string, &sep](const auto &a, const auto &el) { + return std::accumulate((*ceto::mad(v)).cbegin() + 1, (*ceto::mad(v)).cend(), to_string(ceto::bounds_check(v,0)), [&to_string, &sep](const auto &a, const auto &el) { if constexpr (!std::is_void_v) { return ((a + sep) + to_string(el)); } else { static_cast(((a + sep) + to_string(el))); }; }); } - inline auto string_replace(const std::string& source, const std::string& from, const std::string& to) -> auto { + inline auto string_replace(const std::string& source, const std::string& from, const std::string& to) -> auto { auto new_string { std::string() } ; (*ceto::mad(new_string)).reserve((*ceto::mad(source)).length()); std::string::size_type last_pos { 0 } ; static_assert(std::is_convertible_v); @@ -57,12 +58,12 @@ auto join(const T1& v, const T2& to_string, const decltype(std::string {""})& s return new_string; } - template + template auto contains(const T1& container, const typename std::remove_reference_t :: value_type & element) -> auto { return (std::find((*ceto::mad(container)).begin(), (*ceto::mad(container)).end(), element) != (*ceto::mad(container)).end()); } - template + template auto typeid_name(const T1& object) -> auto { #if _MSC_VER const auto name = (*ceto::mad(typeid(object))).name(); @@ -79,3 +80,5 @@ auto typeid_name(const T1& object) -> auto { } + +};