Skip to content

Commit

Permalink
add append vector op
Browse files Browse the repository at this point in the history
  • Loading branch information
on-keyday committed Dec 30, 2024
1 parent 3c513fa commit 040b900
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 193 deletions.
5 changes: 5 additions & 0 deletions astlib/ast2c/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ const char* ast2c_BinaryOp_to_string(ast2c_BinaryOp val) {
case AST2C_BINARYOP_BIT_XOR_ASSIGN: return "^=";
case AST2C_BINARYOP_COMMA: return ",";
case AST2C_BINARYOP_IN_ASSIGN: return "in";
case AST2C_BINARYOP_APPEND_ASSIGN: return "append";
default: return NULL;
}
}
Expand Down Expand Up @@ -699,6 +700,10 @@ int ast2c_BinaryOp_from_string(const char* str, ast2c_BinaryOp* out) {
*out = AST2C_BINARYOP_IN_ASSIGN;
return 1;
}
if (strcmp(str, "append") == 0) {
*out = AST2C_BINARYOP_APPEND_ASSIGN;
return 1;
}
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions astlib/ast2c/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ enum ast2c_BinaryOp {
AST2C_BINARYOP_BIT_XOR_ASSIGN = 38,
AST2C_BINARYOP_COMMA = 39,
AST2C_BINARYOP_IN_ASSIGN = 40,
AST2C_BINARYOP_APPEND_ASSIGN = 41,
};
const char* ast2c_BinaryOp_to_string(ast2c_BinaryOp);
int ast2c_BinaryOp_from_string(const char*,ast2c_BinaryOp*);
Expand Down
1 change: 1 addition & 0 deletions astlib/ast2csharp/ast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ public enum BinaryOp {
BitXorAssign,
Comma,
InAssign,
AppendAssign,
}
public enum IdentUsage {
Unknown,
Expand Down
2 changes: 2 additions & 0 deletions astlib/ast2dart/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ BitXorAssign,
Comma,
@JsonValue('in')
InAssign,
@JsonValue('append')
AppendAssign,
}
enum IdentUsage {
@JsonValue('unknown')
Expand Down
5 changes: 5 additions & 0 deletions astlib/ast2go/ast/ast.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions astlib/ast2py/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class BinaryOp(PyEnum):
BIT_XOR_ASSIGN = "^="
COMMA = ","
IN_ASSIGN = "in"
APPEND_ASSIGN = "append"


class IdentUsage(PyEnum):
Expand Down
3 changes: 3 additions & 0 deletions astlib/ast2rust/core/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ pub enum BinaryOp {
BitXorAssign,
Comma,
InAssign,
AppendAssign,
}
impl TryFrom<&str> for BinaryOp {
type Error = ();
Expand Down Expand Up @@ -651,6 +652,7 @@ impl TryFrom<&str> for BinaryOp {
"^=" =>Ok(Self::BitXorAssign),
"," =>Ok(Self::Comma),
"in" =>Ok(Self::InAssign),
"append" =>Ok(Self::AppendAssign),
_=> Err(()),
}
}
Expand Down Expand Up @@ -700,6 +702,7 @@ impl BinaryOp {
Self::BitXorAssign => "^=",
Self::Comma => ",",
Self::InAssign => "in",
Self::AppendAssign => "append",
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion astlib/ast2ts/src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ export const enum BinaryOp {
bit_xor_assign = "^=",
comma = ",",
in_assign = "in",
append_assign = "append",
};

export function isBinaryOp(obj: any): obj is BinaryOp {
return obj && typeof obj === 'string' && (obj === "*" || obj === "/" || obj === "%" || obj === "<<<" || obj === ">>>" || obj === "<<" || obj === ">>" || obj === "&" || obj === "+" || obj === "-" || obj === "|" || obj === "^" || obj === "==" || obj === "!=" || obj === "<" || obj === "<=" || obj === ">" || obj === ">=" || obj === "&&" || obj === "||" || obj === "?" || obj === ":" || obj === ".." || obj === "..=" || obj === "=" || obj === ":=" || obj === "::=" || obj === "+=" || obj === "-=" || obj === "*=" || obj === "/=" || obj === "%=" || obj === "<<=" || obj === ">>=" || obj === "<<<=" || obj === ">>>=" || obj === "&=" || obj === "|=" || obj === "^=" || obj === "," || obj === "in")
return obj && typeof obj === 'string' && (obj === "*" || obj === "/" || obj === "%" || obj === "<<<" || obj === ">>>" || obj === "<<" || obj === ">>" || obj === "&" || obj === "+" || obj === "-" || obj === "|" || obj === "^" || obj === "==" || obj === "!=" || obj === "<" || obj === "<=" || obj === ">" || obj === ">=" || obj === "&&" || obj === "||" || obj === "?" || obj === ":" || obj === ".." || obj === "..=" || obj === "=" || obj === ":=" || obj === "::=" || obj === "+=" || obj === "-=" || obj === "*=" || obj === "/=" || obj === "%=" || obj === "<<=" || obj === ">>=" || obj === "<<<=" || obj === ">>>=" || obj === "&=" || obj === "|=" || obj === "^=" || obj === "," || obj === "in" || obj === "append")
}

export const enum IdentUsage {
Expand Down
1 change: 1 addition & 0 deletions example/brgen_help/ast_enum.bgn
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum BinaryOp:

comma = ","
in_assign = "in"
append_assign = "append" # special case for array append

enum UnaryOp:
not_ = "!"
Expand Down
6 changes: 3 additions & 3 deletions src/core/ast/expr_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace brgen::ast {
"&=", "|=", "^=",
};
constexpr const char* bin_layer8[] = {","};
constexpr const char* ignored_layer[] = {"in"};
constexpr const char* ignored_layer[] = {"in","append"};



Expand All @@ -34,7 +34,7 @@ namespace brgen::ast {
"..", "..=",
"=", ":=", "::=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=","<<<=",">>>=", "&=", "|=", "^=",
",",
"in",
"in","append",
nullptr,
};

Expand All @@ -48,7 +48,7 @@ namespace brgen::ast {
"range_exclusive", "range_inclusive",
"assign", "define_assign", "const_assign", "add_assign", "sub_assign", "mul_assign", "div_assign", "mod_assign", "left_logical_shift_assign", "right_logical_shift_assign","left_arithmetic_shift_assign","right_arithmetic_shift_assign", "bit_and_assign", "bit_or_assign", "bit_xor_assign",
"comma",
"in",
"in","append",
nullptr,
};
// clang-format on
Expand Down
11 changes: 8 additions & 3 deletions src/core/ast/node/ast_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ enum class BinaryOp {
bit_xor_assign = 38,
comma = 39,
in_assign = 40,
append_assign = 41,
};
constexpr const char* to_string(BinaryOp e) {
switch(e) {
Expand Down Expand Up @@ -170,6 +171,7 @@ constexpr const char* to_string(BinaryOp e) {
case BinaryOp::bit_xor_assign: return "^=";
case BinaryOp::comma: return ",";
case BinaryOp::in_assign: return "in";
case BinaryOp::append_assign: return "append";
default: return nullptr;
}
}
Expand Down Expand Up @@ -216,12 +218,13 @@ template<>constexpr std::optional<BinaryOp> from_string<BinaryOp>(std::string_vi
if(str == "^=") return BinaryOp::bit_xor_assign;
if(str == ",") return BinaryOp::comma;
if(str == "in") return BinaryOp::in_assign;
if(str == "append") return BinaryOp::append_assign;
return std::nullopt;
}
template<>constexpr size_t enum_elem_count<BinaryOp>() {
return 41;
return 42;
}
template<>constexpr std::array<std::pair<BinaryOp,std::string_view>,41> make_enum_array<BinaryOp>() {
template<>constexpr std::array<std::pair<BinaryOp,std::string_view>,42> make_enum_array<BinaryOp>() {
return {
std::pair{BinaryOp::mul,"*"},
std::pair{BinaryOp::div,"/"},
Expand Down Expand Up @@ -264,9 +267,10 @@ template<>constexpr std::array<std::pair<BinaryOp,std::string_view>,41> make_enu
std::pair{BinaryOp::bit_xor_assign,"^="},
std::pair{BinaryOp::comma,","},
std::pair{BinaryOp::in_assign,"in"},
std::pair{BinaryOp::append_assign,"append"},
};
}
template<>constexpr std::array<std::pair<BinaryOp,std::string_view>,41> make_enum_name_array<BinaryOp>() {
template<>constexpr std::array<std::pair<BinaryOp,std::string_view>,42> make_enum_name_array<BinaryOp>() {
return {
std::pair{BinaryOp::mul,"mul"},
std::pair{BinaryOp::div,"div"},
Expand Down Expand Up @@ -309,6 +313,7 @@ template<>constexpr std::array<std::pair<BinaryOp,std::string_view>,41> make_enu
std::pair{BinaryOp::bit_xor_assign,"bit_xor_assign"},
std::pair{BinaryOp::comma,"comma"},
std::pair{BinaryOp::in_assign,"in_assign"},
std::pair{BinaryOp::append_assign,"append_assign"},
};
}
constexpr void as_json(BinaryOp e,auto&& d) {
Expand Down
35 changes: 35 additions & 0 deletions src/core/ast/node/deep_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ namespace brgen::ast {
for (auto& i : node->metadata) {
new_node->metadata.push_back(deep_copy(i.lock(), std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map)));
}
new_node->endian = deep_copy(node->endian.lock(), std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map));
return new_node;
}
template <class NodeM, class ScopeM>
Expand Down Expand Up @@ -535,6 +536,9 @@ namespace brgen::ast {
for (auto& i : node->arguments) {
new_node->arguments.push_back(deep_copy(i, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map)));
}
for (auto& i : node->assigns) {
new_node->assigns.push_back(deep_copy(i, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map)));
}
new_node->alignment = deep_copy(node->alignment, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map));
new_node->alignment_value = node->alignment_value;
new_node->sub_byte_length = deep_copy(node->sub_byte_length, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map));
Expand Down Expand Up @@ -733,6 +737,7 @@ namespace brgen::ast {
for (auto& i : node->branch) {
new_node->branch.push_back(deep_copy(i, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map)));
}
new_node->trial_match = node->trial_match;
return new_node;
}
template <class NodeM, class ScopeM>
Expand Down Expand Up @@ -817,6 +822,9 @@ namespace brgen::ast {
new_node->expr_type = deep_copy(node->expr_type, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map));
new_node->constant_level = node->constant_level;
new_node->base = deep_copy(node->base, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map));
for (auto& i : node->arguments) {
new_node->arguments.push_back(deep_copy(i, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map)));
}
return new_node;
}
template <class NodeM, class ScopeM>
Expand Down Expand Up @@ -1320,6 +1328,7 @@ namespace brgen::ast {
new_node->recursive = node->recursive;
new_node->fixed_header_size = node->fixed_header_size;
new_node->fixed_tail_size = node->fixed_tail_size;
new_node->type_map = deep_copy(node->type_map, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map));
return new_node;
}
template <class NodeM, class ScopeM>
Expand Down Expand Up @@ -2841,6 +2850,10 @@ namespace brgen::ast {
return false;
}
}
if (!deep_equal(a->endian.lock(), b->endian.lock(), std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map), std::forward<BackTracer>(trace))) {
trace(a->endian.lock(), b->endian.lock(), "Program::endian", -1);
return false;
}
return true;
}
template <class NodeM, class ScopeM, class BackTracer = NullBackTracer>
Expand Down Expand Up @@ -2937,6 +2950,13 @@ namespace brgen::ast {
return false;
}
}
if (a->assigns.size() != b->assigns.size()) return false;
for (size_t i = 0; i < a->assigns.size(); i++) {
if (!deep_equal(a->assigns[i], b->assigns[i], std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map), std::forward<BackTracer>(trace))) {
trace(a->assigns[i], b->assigns[i], "FieldArgument::assigns", i);
return false;
}
}
if (!deep_equal(a->alignment, b->alignment, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map), std::forward<BackTracer>(trace))) {
trace(a->alignment, b->alignment, "FieldArgument::alignment", -1);
return false;
Expand Down Expand Up @@ -3404,6 +3424,10 @@ namespace brgen::ast {
return false;
}
}
if (a->trial_match != b->trial_match) {
trace(a->trial_match, b->trial_match, "Match::trial_match", -1);
return false;
}
return true;
}
template <class NodeM, class ScopeM, class BackTracer = NullBackTracer>
Expand Down Expand Up @@ -3585,6 +3609,13 @@ namespace brgen::ast {
trace(a->base, b->base, "Cast::base", -1);
return false;
}
if (a->arguments.size() != b->arguments.size()) return false;
for (size_t i = 0; i < a->arguments.size(); i++) {
if (!deep_equal(a->arguments[i], b->arguments[i], std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map), std::forward<BackTracer>(trace))) {
trace(a->arguments[i], b->arguments[i], "Cast::arguments", i);
return false;
}
}
return true;
}
template <class NodeM, class ScopeM, class BackTracer = NullBackTracer>
Expand Down Expand Up @@ -4694,6 +4725,10 @@ namespace brgen::ast {
trace(a->fixed_tail_size, b->fixed_tail_size, "StructType::fixed_tail_size", -1);
return false;
}
if (!deep_equal(a->type_map, b->type_map, std::forward<NodeM>(node_map), std::forward<ScopeM>(scope_map), std::forward<BackTracer>(trace))) {
trace(a->type_map, b->type_map, "StructType::type_map", -1);
return false;
}
return true;
}
template <class NodeM, class ScopeM, class BackTracer = NullBackTracer>
Expand Down
47 changes: 47 additions & 0 deletions src/core/middle/typing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,50 @@ namespace brgen::middle {
}
}

void check_and_set_vector_append(const std::shared_ptr<ast::Binary>& b) {
if (b->op != ast::BinaryOp::assign) {
return;
}
auto left = ast::as<ast::Index>(b->left);
if (!left) {
return;
}
auto member_access = ast::as<ast::MemberAccess>(left->index);
if (!member_access) {
return;
}
if (member_access->member->usage != ast::IdentUsage::reference_builtin_fn ||
member_access->member->ident != "length") {
return;
}
auto recursive_detect = [&](auto&& f, ast::Node* l, ast::Node* r) -> void {
if (auto l_ident = ast::as<ast::Ident>(l)) {
if (auto r_ident = ast::as<ast::Ident>(r)) {
if (l_ident->base.lock() == r_ident->base.lock()) {
b->op = ast::BinaryOp::append_assign; // vector.append
return;
}
}
}
else if (auto l_index = ast::as<ast::Index>(l)) {
if (auto r_index = ast::as<ast::Index>(r)) {
f(f, l_index->index.get(), r_index->index.get());
return;
}
}
else if (auto member_access_l = ast::as<ast::MemberAccess>(l)) {
if (auto member_access_r = ast::as<ast::MemberAccess>(r)) {
if (member_access_l->base.lock() == member_access_r->base.lock()) {
f(f, member_access_l->target.get(), member_access_r->target.get());
return;
}
return;
}
}
};
recursive_detect(recursive_detect, member_access->target.get(), left->expr.get());
}

void typing_assign(const std::shared_ptr<ast::Binary>& b) {
auto right = b->right;
auto check_right_typed = [&] {
Expand All @@ -156,6 +200,8 @@ namespace brgen::middle {
};

auto handle_member_or_index_access = [&](const auto& access_node) {
assert(b->op != ast::BinaryOp::define_assign &&
b->op != ast::BinaryOp::const_assign);
if (!access_node->expr_type) {
warn_not_typed(access_node);
return false;
Expand All @@ -167,6 +213,7 @@ namespace brgen::middle {
if (!equal_type(access_node->expr_type, right->expr_type)) {
report_not_equal_type(access_node->loc, access_node->expr_type, right->expr_type);
}
check_and_set_vector_append(b);
return true;
};

Expand Down
Loading

0 comments on commit 040b900

Please sign in to comment.