This commit is contained in:
bronku 2025-12-06 12:35:51 +01:00
parent a47ef094af
commit c516afc400
13 changed files with 240 additions and 184 deletions

View file

@ -24,7 +24,17 @@ struct BinaryOperator
LSHIFT, LSHIFT,
RSHIFT, RSHIFT,
POWER, POWER,
IN IN,
PLUS_ASSIGN,
MINUS_ASSIGN,
MULTIPLY_ASSIGN,
DIVIDE_ASSIGN,
MODULO_ASSIGN,
BIT_AND_ASSIGN,
BIT_OR_ASSIGN,
BIT_XOR_ASSIGN,
LSHIFT_ASSIGN,
RSHIFT_ASSIGN,
}; };
Kind kind; Kind kind;
@ -75,6 +85,26 @@ struct BinaryOperator
return "**"; return "**";
case IN: case IN:
return "in"; return "in";
case PLUS_ASSIGN:
return "+=";
case MINUS_ASSIGN:
return "-=";
case MULTIPLY_ASSIGN:
return "*=";
case DIVIDE_ASSIGN:
return "/=";
case MODULO_ASSIGN:
return "%=";
case BIT_AND_ASSIGN:
return "&=";
case BIT_OR_ASSIGN:
return "|=";
case BIT_XOR_ASSIGN:
return "^=";
case LSHIFT_ASSIGN:
return "<<=";
case RSHIFT_ASSIGN:
return ">>=";
default: default:
return "?"; return "?";
} }

View file

@ -25,6 +25,25 @@ struct Assign : Stmt
} }
}; };
struct OpAssign : Stmt
{
ptr<Expr> target;
ptr<Expr> value;
BinaryOperator op;
OpAssign(ptr<Expr> t, ptr<Expr> v, BinaryOperator o)
: target(std::move(t)), value(std::move(v)), op(o) {}
std::string dump(int indent = 0) const override
{
std::ostringstream oss;
oss << indent_str(indent) << "OpAssign(" << op.symbol() << ")\n";
oss << target->dump(indent + 1) << "\n";
oss << value->dump(indent + 1);
return oss.str();
}
};
struct ExprStmt : Stmt struct ExprStmt : Stmt
{ {
ptr<Expr> expr; ptr<Expr> expr;

View file

@ -118,6 +118,14 @@ private:
generate_expr(*assign->value); generate_expr(*assign->value);
write("\n"); write("\n");
} }
else if (auto *assign = dynamic_cast<const OpAssign *>(&stmt))
{
write_indent();
generate_expr(*assign->target);
output << " " << assign->op.symbol() << " ";
generate_expr(*assign->value);
write("\n");
}
else if (auto *if_stmt = dynamic_cast<const If *>(&stmt)) else if (auto *if_stmt = dynamic_cast<const If *>(&stmt))
{ {
write_indent(); write_indent();

View file

@ -82,6 +82,36 @@ stmt:
| expr ASSIGN expr NEWLINE { | expr ASSIGN expr NEWLINE {
$$ = std::make_unique<Assign>(std::move($1), std::move($3)); $$ = std::make_unique<Assign>(std::move($1), std::move($3));
} }
| expr PLUS_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::PLUS_ASSIGN));
}
| expr MINUS_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::MINUS_ASSIGN));
}
| expr MULTIPLY_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::MULTIPLY_ASSIGN));
}
| expr DIVIDE_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::DIVIDE_ASSIGN));
}
| expr MODULO_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::MODULO_ASSIGN));
}
| expr BIT_AND_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::BIT_AND_ASSIGN));
}
| expr BIT_OR_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::BIT_OR_ASSIGN));
}
| expr BIT_XOR_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::BIT_XOR_ASSIGN));
}
| expr LSHIFT_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::LSHIFT_ASSIGN));
}
| expr RSHIFT_ASSIGN expr NEWLINE {
$$ = std::make_unique<OpAssign>(std::move($1), std::move($3), BinaryOperator(BinaryOperator::RSHIFT_ASSIGN));
}
| KW_IF expr COLON NEWLINE INDENT stmt_list DEDENT elif_chain{ | KW_IF expr COLON NEWLINE INDENT stmt_list DEDENT elif_chain{
$$ = std::make_unique<If>(std::move($2), std::move($6), std::move($8)); $$ = std::make_unique<If>(std::move($2), std::move($6), std::move($8));
} }

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] = word_count[word] + 1 word_count[word] += 1
else: else:
word_count[word] = 1 word_count[word] = 1

View file

@ -11,7 +11,7 @@ def count_words(text)
for word in words for word in words
word = word.delete('.,!?') word = word.delete('.,!?')
if __contains__(word_count, word) if __contains__(word_count, word)
word_count[word] = word_count[word] + 1 word_count[word] += 1
else else
word_count[word] = 1 word_count[word] = 1
end end

View file

@ -1,31 +1,34 @@
def count_words(text): class BankAccount:
words = text.lower().split() def __init__(self, owner, balance=0):
word_count = {} self.owner = owner
self.balance = balance
for word in words: def deposit(self, amount):
word = word.strip('.,!?') if amount > 0:
if word in word_count: self.balance += amount
word_count[word] = word_count[word] + 1 return True
else: return False
word_count[word] = 1
return word_count def withdraw(self, amount):
if 0 < amount <= self.balance:
self.balance -= amount
return True
return False
def find_most_common(word_count): def get_balance(self):
most_common = None return self.balance
max_count = 0
for word, count in word_count.items(): def __str__(self):
if count > max_count: return f"Account({self.owner}, Balance: ${self.balance:.2f})"
most_common = word
max_count = count
return most_common, max_count account = BankAccount("Alice", 1000)
print(account)
text = "Hello world hello there world hello" print(f"Deposit $500: {account.deposit(500)}")
counts = count_words(text) print(f"Balance: ${account.get_balance()}")
common_word, frequency = find_most_common(counts)
print(f"Text: {text}") print(f"Withdraw $200: {account.withdraw(200)}")
print(f"Word counts: {counts}") print(f"Balance: ${account.get_balance()}")
print(f"Most common: '{common_word}' appears {frequency} times")
print(f"Withdraw $2000: {account.withdraw(2000)}")
print(f"Final balance: ${account.get_balance()}")

View file

@ -1,34 +1,18 @@
class BankAccount: def write_to_file(filename, content):
def __init__(self, owner, balance=0): with open(filename, 'w') as file:
self.owner = owner file.write(content)
self.balance = balance print(f"Written to {filename}")
def deposit(self, amount): def read_from_file(filename):
if amount > 0: try:
self.balance += amount with open(filename, 'r') as file:
return True content = file.read()
return False return content
except FileNotFoundError:
return "File not found"
def withdraw(self, amount): write_to_file("test_output.txt", "Hello, World!\nThis is a test.\n")
if 0 < amount <= self.balance: content = read_from_file("test_output.txt")
self.balance -= amount print(f"File content:\n{content}")
return True
return False
def get_balance(self): print(read_from_file("nonexistent.txt"))
return self.balance
def __str__(self):
return f"Account({self.owner}, Balance: ${self.balance:.2f})"
account = BankAccount("Alice", 1000)
print(account)
print(f"Deposit $500: {account.deposit(500)}")
print(f"Balance: ${account.get_balance()}")
print(f"Withdraw $200: {account.withdraw(200)}")
print(f"Balance: ${account.get_balance()}")
print(f"Withdraw $2000: {account.withdraw(2000)}")
print(f"Final balance: ${account.get_balance()}")

View file

@ -1,18 +1,33 @@
def write_to_file(filename, content): import math
with open(filename, 'w') as file:
file.write(content)
print(f"Written to {filename}")
def read_from_file(filename): def circle_area(radius):
try: return math.pi * radius ** 2
with open(filename, 'r') as file:
content = file.read()
return content
except FileNotFoundError:
return "File not found"
write_to_file("test_output.txt", "Hello, World!\nThis is a test.\n") def circle_circumference(radius):
content = read_from_file("test_output.txt") return 2 * math.pi * radius
print(f"File content:\n{content}")
print(read_from_file("nonexistent.txt")) def solve_quadratic(a, b, c):
discriminant = b ** 2 - 4 * a * c
if discriminant < 0:
return None, None
elif discriminant == 0:
x = -b / (2 * a)
return x, x
else:
x1 = (-b + math.sqrt(discriminant)) / (2 * a)
x2 = (-b - math.sqrt(discriminant)) / (2 * a)
return x1, x2
print(f"Circle with radius 5:")
print(f" Area: {circle_area(5):.2f}")
print(f" Circumference: {circle_circumference(5):.2f}")
print(f"\nQuadratic 2x² + 5x - 3 = 0:")
x1, x2 = solve_quadratic(2, 5, -3)
print(f" Solutions: {x1:.2f}, {x2:.2f}")
print(f"\nQuadratic x² + 1 = 0:")
x1, x2 = solve_quadratic(1, 0, 1)
if x1 is None:
print(" No real solutions")

View file

@ -1,33 +1,29 @@
import math def countdown(n):
while n > 0:
print(f"Countdown: {n}")
n -= 1
print("Blast off!")
def circle_area(radius): def sum_until_negative():
return math.pi * radius ** 2 total = 0
count = 0
inputs = [5, 3, 8, -1, 4, 2]
def circle_circumference(radius): for value in inputs:
return 2 * math.pi * radius if value < 0:
break
total += value
count += 1
def solve_quadratic(a, b, c): if count > 0:
discriminant = b ** 2 - 4 * a * c average = total / count
return total, average
if discriminant < 0:
return None, None
elif discriminant == 0:
x = -b / (2 * a)
return x, x
else: else:
x1 = (-b + math.sqrt(discriminant)) / (2 * a) return 0, 0
x2 = (-b - math.sqrt(discriminant)) / (2 * a)
return x1, x2
print(f"Circle with radius 5:") print("Countdown from 5:")
print(f" Area: {circle_area(5):.2f}") countdown(5)
print(f" Circumference: {circle_circumference(5):.2f}")
print(f"\nQuadratic 2x² + 5x - 3 = 0:") print("\nSum until negative:")
x1, x2 = solve_quadratic(2, 5, -3) total, avg = sum_until_negative()
print(f" Solutions: {x1:.2f}, {x2:.2f}") print(f"Total: {total}, Average: {avg:.2f}")
print(f"\nQuadratic x² + 1 = 0:")
x1, x2 = solve_quadratic(1, 0, 1)
if x1 is None:
print(" No real solutions")

View file

@ -1,29 +1,30 @@
def countdown(n): def analyze_numbers(numbers):
while n > 0: if not numbers:
print(f"Countdown: {n}") return 0, 0, 0
n -= 1
print("Blast off!")
def sum_until_negative(): total = sum(numbers)
total = 0 average = total / len(numbers)
count = 0
inputs = [5, 3, 8, -1, 4, 2]
for value in inputs: positive_count = 0
if value < 0: for num in numbers:
break if num > 0:
total += value positive_count += 1
count += 1
if count > 0: return total, average, positive_count
average = total / count
return total, average
else:
return 0, 0
print("Countdown from 5:") def get_coordinates():
countdown(5) x = 10
y = 20
z = 30
return x, y, z
print("\nSum until negative:") data = [3, -1, 4, -2, 0, 5, -3]
total, avg = sum_until_negative() total, avg, positives = analyze_numbers(data)
print(f"Total: {total}, Average: {avg:.2f}")
print(f"Numbers: {data}")
print(f"Total: {total}")
print(f"Average: {avg:.2f}")
print(f"Positive numbers: {positives}")
x, y, z = get_coordinates()
print(f"\nCoordinates: x={x}, y={y}, z={z}")

View file

@ -1,30 +1,31 @@
def analyze_numbers(numbers): def count_words(text):
if not numbers: words = text.lower().split()
return 0, 0, 0 word_count = {}
total = sum(numbers) for word in words:
average = total / len(numbers) word = word.strip('.,!?')
if word in word_count:
word_count[word] = word_count[word] + 1
else:
word_count[word] = 1
positive_count = 0 return word_count
for num in numbers:
if num > 0:
positive_count += 1
return total, average, positive_count def find_most_common(word_count):
most_common = None
max_count = 0
def get_coordinates(): for word, count in word_count.items():
x = 10 if count > max_count:
y = 20 most_common = word
z = 30 max_count = count
return x, y, z
data = [3, -1, 4, -2, 0, 5, -3] return most_common, max_count
total, avg, positives = analyze_numbers(data)
print(f"Numbers: {data}") text = "Hello world hello there world hello"
print(f"Total: {total}") counts = count_words(text)
print(f"Average: {avg:.2f}") common_word, frequency = find_most_common(counts)
print(f"Positive numbers: {positives}")
x, y, z = get_coordinates() print(f"Text: {text}")
print(f"\nCoordinates: x={x}, y={y}, z={z}") print(f"Word counts: {counts}")
print(f"Most common: '{common_word}' appears {frequency} times")

View file

@ -1,31 +0,0 @@
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")