okokokokokook

This commit is contained in:
bronku 2025-12-06 12:16:48 +01:00
parent 61dc873489
commit a47ef094af
9 changed files with 136 additions and 25 deletions

View file

@ -1,5 +1,6 @@
- string processing is very primitive, it just checks for f at the beggining, and then adds #, before { if so - string processing is very primitive, it just checks for f at the beggining, and then adds #, before { if so
- no elif - no elif parsed as if else if else if else .... insted of if elif elif else, semantically the same
- no lambdas - no lambdas
- tuples need to be in () - tuples need to be in ()
- converts tuples into lists - converts tuples into lists
- no += -= *= /= ...

View file

@ -23,7 +23,8 @@ struct BinaryOperator
BIT_XOR, BIT_XOR,
LSHIFT, LSHIFT,
RSHIFT, RSHIFT,
POWER POWER,
IN
}; };
Kind kind; Kind kind;
@ -72,6 +73,8 @@ struct BinaryOperator
return ">>"; return ">>";
case POWER: case POWER:
return "**"; return "**";
case IN:
return "in";
default: default:
return "?"; return "?";
} }

View file

@ -83,7 +83,6 @@ struct Continue : Stmt
} }
}; };
// #todo elif
struct If : Stmt struct If : Stmt
{ {
ptr<Expr> condition; ptr<Expr> condition;

View file

@ -27,6 +27,7 @@ class RubyGenerator
{ {
std::ostringstream output; std::ostringstream output;
int indent_level = 0; int indent_level = 0;
bool write_contains = false;
void write_indent() void write_indent()
{ {
@ -52,6 +53,29 @@ public:
generate_stmt(*stmt); generate_stmt(*stmt);
} }
std::string tmp = output.str();
output.str("");
output.clear();
if (write_contains)
{
output << "def __contains__(container, item)" << "\n"
<< " if container.is_a?(Hash)"
<< "\n"
<< " container.key?(item)"
<< "\n"
<< " else"
<< "\n"
<< " container.include?(item)"
<< "\n"
<< " end"
<< "\n"
<< "end"
<< "\n";
}
output << tmp;
return output.str(); return output.str();
} }
@ -271,9 +295,22 @@ private:
} }
else if (auto *binop = dynamic_cast<const BinOp *>(&expr)) else if (auto *binop = dynamic_cast<const BinOp *>(&expr))
{ {
generate_expr(*binop->left); if (binop->op.kind == BinaryOperator::IN)
write(" " + binop->op.symbol() + " "); {
generate_expr(*binop->right); write("__contains__(");
generate_expr(*binop->right);
write(", ");
generate_expr(*binop->left);
write(")");
write_contains = true;
return;
}
else
{
generate_expr(*binop->left);
write(" " + binop->op.symbol() + " ");
generate_expr(*binop->right);
}
} }
else if (auto *call = dynamic_cast<const Call *>(&expr)) else if (auto *call = dynamic_cast<const Call *>(&expr))
{ {
@ -416,7 +453,18 @@ private:
} }
generate_expr(*attr->value); generate_expr(*attr->value);
output << "." << attr->attr; if (attr->attr == "lower")
{
output << "." << "downcase";
}
else if (attr->attr == "strip")
{
output << "." << "delete";
}
else
{
output << "." << attr->attr;
}
} }
else if (auto *subscript = dynamic_cast<const Subscript *>(&expr)) else if (auto *subscript = dynamic_cast<const Subscript *>(&expr))
{ {

View file

@ -62,6 +62,7 @@
%type <std::vector<std::unique_ptr<Stmt>>> stmt_list %type <std::vector<std::unique_ptr<Stmt>>> stmt_list
%type <std::vector<std::string>> params %type <std::vector<std::string>> params
%type <std::vector<std::unique_ptr<Stmt>>> elif_chain %type <std::vector<std::unique_ptr<Stmt>>> elif_chain
%type <std::vector<std::pair<std::unique_ptr<Expr>, std::unique_ptr<Expr>>>> dict_pairs
%% %%
@ -122,7 +123,8 @@ expr:
| expr MINUS expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::SUB), std::move($1), std::move($3)); } | expr MINUS expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::SUB), std::move($1), std::move($3)); }
| expr LT expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::LT) , std::move($1), std::move($3)); } | expr LT expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::LT) , std::move($1), std::move($3)); }
| expr GT expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::GT) , std::move($1), std::move($3)); } | expr GT expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::GT) , std::move($1), std::move($3)); }
| expr GTE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::GTE) , std::move($1), std::move($3)); } | expr GTE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::GTE) , std::move($1), std::move($3)); }
| expr NE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::NE) , std::move($1), std::move($3)); }
| expr KW_AND expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::AND) , std::move($1), std::move($3)); } | expr KW_AND expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::AND) , std::move($1), std::move($3)); }
| expr KW_OR expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::OR) , std::move($1), std::move($3)); } | expr KW_OR expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::OR) , std::move($1), std::move($3)); }
| expr LTE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::LTE) , std::move($1), std::move($3)); } | expr LTE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::LTE) , std::move($1), std::move($3)); }
@ -130,6 +132,7 @@ expr:
| expr MODULO expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::MOD) , std::move($1), std::move($3)); } | expr MODULO expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::MOD) , std::move($1), std::move($3)); }
| expr EQ expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::EQ) , std::move($1), std::move($3)); } | expr EQ expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::EQ) , std::move($1), std::move($3)); }
| expr DIVIDE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::DIV) , std::move($1), std::move($3)); } | expr DIVIDE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::DIV) , std::move($1), std::move($3)); }
| expr KW_IN expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::IN) , std::move($1), std::move($3)); }
| KW_NOT expr { $$ = std::make_unique<UnaryOpExpr>( UnaryOperator(UnaryOperator::NOT) , std::move($2)); } | KW_NOT expr { $$ = std::make_unique<UnaryOpExpr>( UnaryOperator(UnaryOperator::NOT) , std::move($2)); }
| expr L_BRACKET expr R_BRACKET { $$ = std::make_unique<Subscript>(std::move($1), std::move($3));} | expr L_BRACKET expr R_BRACKET { $$ = std::make_unique<Subscript>(std::move($1), std::move($3));}
| expr L_BRACKET slice R_BRACKET{ $$ = std::make_unique<SliceSubscript>(std::move($1), std::move($3)); } | expr L_BRACKET slice R_BRACKET{ $$ = std::make_unique<SliceSubscript>(std::move($1), std::move($3)); }
@ -139,6 +142,8 @@ expr:
| L_BRACKET args R_BRACKET { $$ = std::make_unique<List>(std::move($2));} | L_BRACKET args R_BRACKET { $$ = std::make_unique<List>(std::move($2));}
| L_PAREN tuple R_PAREN { $$ = std::make_unique<Tuple>(std::move($2));} | L_PAREN tuple R_PAREN { $$ = std::make_unique<Tuple>(std::move($2));}
| MINUS expr { $$ = std::make_unique<UnaryOpExpr>(UnaryOperator(UnaryOperator::NEG), std::move($2));} | MINUS expr { $$ = std::make_unique<UnaryOpExpr>(UnaryOperator(UnaryOperator::NEG), std::move($2));}
| L_BRACE dict_pairs R_BRACE { $$ = std::make_unique<Dict>(std::move($2)); }
| L_BRACE R_BRACE { $$ = std::make_unique<Dict>(std::vector<std::pair<std::unique_ptr<Expr>, std::unique_ptr<Expr>>>()); }
; ;
slice: slice:
@ -180,6 +185,19 @@ elif_chain:
$$ = std::move($5); $$ = std::move($5);
} }
; ;
dict_pairs:
expr COLON expr
{
$$ = std::vector<std::pair<std::unique_ptr<Expr>, std::unique_ptr<Expr>>>();
$$.push_back(std::make_pair(std::move($1), std::move($3)));
}
| dict_pairs COMMA expr COLON expr
{
$1.push_back(std::make_pair(std::move($3), std::move($5)));
$$ = std::move($1);
}
;
%% %%
namespace yy { namespace yy {
void parser::error(const std::string& msg) void parser::error(const std::string& msg)

View file

@ -5,27 +5,14 @@ def count_words(text):
for word in words: for word in words:
word = word.strip('.,!?') word = word.strip('.,!?')
if word in word_count: if word in word_count:
word_count[word] += 1 word_count[word] = word_count[word] + 1
else: else:
word_count[word] = 1 word_count[word] = 1
return word_count return word_count
def find_most_common(word_count):
most_common = None
max_count = 0
for word, count in word_count.items():
if count > max_count:
most_common = word
max_count = count
return most_common, max_count
text = "Hello world hello there world hello" text = "Hello world hello there world hello"
counts = count_words(text) counts = count_words(text)
common_word, frequency = find_most_common(counts)
print(f"Text: {text}") print(f"Text: {text}")
print(f"Word counts: {counts}") print(f"Word counts: {counts}")
print(f"Most common: '{common_word}' appears {frequency} times")

24
test/ruby/27.out Normal file
View file

@ -0,0 +1,24 @@
def __contains__(container, item)
if container.is_a?(Hash)
container.key?(item)
else
container.include?(item)
end
end
def count_words(text)
words = text.downcase().split()
word_count = {}
for word in words
word = word.delete('.,!?')
if __contains__(word_count, word)
word_count[word] = word_count[word] + 1
else
word_count[word] = 1
end
end
return word_count
end
text = "Hello world hello there world hello"
counts = count_words(text)
print("Text: #{text}", "\n")
print("Word counts: #{counts}", "\n")

View file

@ -5,7 +5,7 @@ def count_words(text):
for word in words: for word in words:
word = word.strip('.,!?') word = word.strip('.,!?')
if word in word_count: if word in word_count:
word_count[word] += 1 word_count[word] = word_count[word] + 1
else: else:
word_count[word] = 1 word_count[word] = 1

31
test/ruby/34.in Normal file
View file

@ -0,0 +1,31 @@
def count_words(text):
words = text.lower().split()
word_count = {}
for word in words:
word = word.strip('.,!?')
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
return word_count
def find_most_common(word_count):
most_common = None
max_count = 0
for word, count in word_count.items():
if count > max_count:
most_common = word
max_count = count
return most_common, max_count
text = "Hello world hello there world hello"
counts = count_words(text)
common_word, frequency = find_most_common(counts)
print(f"Text: {text}")
print(f"Word counts: {counts}")
print(f"Most common: '{common_word}' appears {frequency} times")