assign
This commit is contained in:
parent
a47ef094af
commit
c516afc400
13 changed files with 240 additions and 184 deletions
|
|
@ -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 "?";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
30
src/parser.y
30
src/parser.y
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()}")
|
||||||
|
|
@ -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()}")
|
|
||||||
|
|
@ -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")
|
||||||
|
|
@ -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")
|
|
||||||
|
|
@ -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}")
|
||||||
|
|
@ -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")
|
||||||
|
|
@ -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")
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue