mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-16 15:08:45 +00:00
Add assignment 4
This commit is contained in:
46
src/assignments/assignment04/context.rs
Normal file
46
src/assignments/assignment04/context.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
//! Calculator.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::*;
|
||||
|
||||
use super::syntax::{Command, Expression};
|
||||
|
||||
/// Calculator's context.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Context {
|
||||
anonymous_counter: usize,
|
||||
variables: HashMap<String, f64>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Creates a new context.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Returns the current anonymous variable counter.
|
||||
pub fn current_counter(&self) -> usize {
|
||||
self.anonymous_counter
|
||||
}
|
||||
|
||||
/// Calculates the given expression.
|
||||
pub fn calc_expression(&self, expression: &Expression) -> Result<f64> {
|
||||
todo!("fill here")
|
||||
}
|
||||
|
||||
/// Calculates the given command.
|
||||
///
|
||||
/// If there is no variable lhs in the command (i.e. `command.variable = None`), its value should be stored at `$0`, `$1`, `$2`, ... respectively.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// After calculating commad `3 + 5` => Context's variables = `{($0,8)}`
|
||||
///
|
||||
/// After calculating commad `v = 3 - 2` => Context's variables = `{($0,8),(v,1))}`
|
||||
///
|
||||
/// After calculating commad `3 ^ 2` => Context's variables = `{($0,8),(v,1),($1,9)}`
|
||||
pub fn calc_command(&mut self, command: &Command) -> Result<(String, f64)> {
|
||||
todo!("fill here")
|
||||
}
|
||||
}
|
||||
20
src/assignments/assignment04/mod.rs
Normal file
20
src/assignments/assignment04/mod.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
//! Assignment 4: Designing a calculator.
|
||||
//!
|
||||
//! The primary goal of this assignment is twofold:
|
||||
//! (1) understanding the `pest` third-party library from documentations; and
|
||||
//! (2) using programming concepts you've learned so far to implement a simple arithmetic calculator.
|
||||
//!
|
||||
//! For `pest`, read the following documentations (that contain 90% of the solution):
|
||||
//! - <https://pest.rs/>
|
||||
//! - <https://pest.rs/book/>
|
||||
//! - <https://docs.rs/pest/latest/pest>
|
||||
//!
|
||||
//! For calculator, just reading `syntax.rs` would suffice for you to understand what to do.
|
||||
//!
|
||||
//! You should fill out the `todo!()` placeholders in such a way that `/scripts/grade-04.sh` works fine.
|
||||
//! See `assignment04_grade.rs` and `/scripts/grade-04.sh` for the test script.
|
||||
//! Run `/scripts/prepare-submissions.sh` and submit `/target/assignment04.zip` to <https://gg.kaist.ac.kr>.
|
||||
|
||||
pub mod context;
|
||||
pub mod parser;
|
||||
pub mod syntax;
|
||||
19
src/assignments/assignment04/parser.rs
Normal file
19
src/assignments/assignment04/parser.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
//! Parser.
|
||||
|
||||
use super::syntax::*;
|
||||
use anyhow::Result;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
mod inner {
|
||||
use pest_derive::*;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "assignments/assignment04/syntax.pest"]
|
||||
pub(crate) struct SyntaxParser;
|
||||
}
|
||||
|
||||
/// Parses command.
|
||||
pub fn parse_command(line: &str) -> Result<Command> {
|
||||
todo!("fill here")
|
||||
}
|
||||
17
src/assignments/assignment04/syntax.pest
Normal file
17
src/assignments/assignment04/syntax.pest
Normal file
@@ -0,0 +1,17 @@
|
||||
num = @{ int ~ ("." ~ ASCII_DIGIT*)? ~ (^"e" ~ int)? }
|
||||
int = { ("+" | "-")? ~ ASCII_DIGIT+ }
|
||||
var = { ("$" | ASCII_ALPHA) ~ (ASCII_ALPHA | ASCII_DIGIT)* }
|
||||
|
||||
operation = _{ add | subtract | multiply | divide | power }
|
||||
add = { "+" }
|
||||
subtract = { "-" }
|
||||
multiply = { "*" }
|
||||
divide = { "/" }
|
||||
power = { "^" }
|
||||
|
||||
expr = { term ~ (operation ~ term)* }
|
||||
term = _{ num | var | "(" ~ expr ~ ")" }
|
||||
|
||||
command = _{ SOI ~ (var ~ "=")? ~ expr ~ EOI }
|
||||
|
||||
WHITESPACE = _{ " " | "\t" }
|
||||
43
src/assignments/assignment04/syntax.rs
Normal file
43
src/assignments/assignment04/syntax.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
//! Syntax.
|
||||
|
||||
/// Command of the form "<expression>" or "<var> = <expression>".
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Command {
|
||||
/// Variable (lhs).
|
||||
pub variable: Option<String>,
|
||||
/// Expression (rhs).
|
||||
pub expression: Expression,
|
||||
}
|
||||
|
||||
/// Binary operators.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum BinOp {
|
||||
/// Add.
|
||||
Add,
|
||||
/// Subtract.
|
||||
Subtract,
|
||||
/// Multiply.
|
||||
Multiply,
|
||||
/// Divide.
|
||||
Divide,
|
||||
/// Power.
|
||||
Power,
|
||||
}
|
||||
|
||||
/// Expression.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Expression {
|
||||
/// Number.
|
||||
Num(f64),
|
||||
/// Variable.
|
||||
Variable(String),
|
||||
/// Binary operation.
|
||||
BinOp {
|
||||
/// Operator.
|
||||
op: BinOp,
|
||||
/// Lhs.
|
||||
lhs: Box<Expression>,
|
||||
/// Rhs.
|
||||
rhs: Box<Expression>,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user