using static System.Console; interface Value { string to_string(); bool as_bool() => throw new Exception("bool expected"); int as_int() => throw new Exception("int expected"); } record Bool(bool b) : Value { public bool as_bool() => b; public string to_string() => b.ToString(); } record Int(int i) : Value { public int as_int() => i; public string to_string() => i.ToString(); } interface Expr { Value eval(); } record Const(Value v) : Expr { public Value eval() => v; } record BinOp(Expr e, string op, Expr f) : Expr { public Value eval() { Value x = e.eval(), y = f.eval(); return op switch { "+" => new Int(x.as_int() + y.as_int()), "-" => new Int(x.as_int() - y.as_int()), "*" => new Int(x.as_int() * y.as_int()), "/" => new Int(x.as_int() / y.as_int()), "%" => new Int(x.as_int() % y.as_int()), "==" => new Bool(x.Equals(y)), "!=" => new Bool(!x.Equals(y)), "<" => new Bool(x.as_int() < y.as_int()), "<=" => new Bool(x.as_int() <= y.as_int()), ">" => new Bool(x.as_int() > y.as_int()), ">=" => new Bool(x.as_int() >= y.as_int()), _ => throw new Exception("bad operation") }; } } class Top { static void Main(string[] args) { if (args.Length < 1) { WriteLine("usage: p2 "); return; } Parser p = new(File.ReadAllText(args[0])); WriteLine(p.parse_expr().eval().to_string()); } }