import Spa.Language.Base namespace Spa /-! Scoped quotation syntax for writing object-language programs. `[obj_expr| … ]` builds an `Expr`, `[obj_stmt| … ]` builds a `Stmt`. Example: ``` [obj_stmt| zero := 0; pos := zero + 1; if pos { x := 1 } else { noop }; while x { x := x - 1 } ] ``` -/ /-- Expressions of the object language. -/ declare_syntax_cat obj_expr syntax num : obj_expr syntax ident : obj_expr syntax:65 obj_expr:65 " + " obj_expr:66 : obj_expr syntax:65 obj_expr:65 " - " obj_expr:66 : obj_expr syntax "(" obj_expr ")" : obj_expr /-- Statements of the object language. -/ declare_syntax_cat obj_stmt syntax "noop" : obj_stmt syntax ident " := " obj_expr : obj_stmt syntax "if " obj_expr " { " obj_stmt " } " "else" " { " obj_stmt " } " : obj_stmt syntax "while " obj_expr " { " obj_stmt " } " : obj_stmt syntax:50 obj_stmt:51 "; " obj_stmt:50 : obj_stmt syntax "(" obj_stmt ")" : obj_stmt scoped syntax "[obj_expr| " obj_expr " ]" : term scoped syntax "[obj_stmt| " obj_stmt " ]" : term scoped macro_rules | `([obj_expr| $n:num]) => `(Expr.num $n) | `([obj_expr| $x:ident]) => `(Expr.var $(Lean.quote x.getId.toString)) | `([obj_expr| $a + $b]) => `(Expr.add [obj_expr| $a] [obj_expr| $b]) | `([obj_expr| $a - $b]) => `(Expr.sub [obj_expr| $a] [obj_expr| $b]) | `([obj_expr| ($e:obj_expr)]) => `([obj_expr| $e]) scoped macro_rules | `([obj_stmt| noop]) => `(Stmt.basic .noop) | `([obj_stmt| $x:ident := $e]) => `(Stmt.basic (.assign $(Lean.quote x.getId.toString) [obj_expr| $e])) | `([obj_stmt| $s₁ ; $s₂]) => `(Stmt.andThen [obj_stmt| $s₁] [obj_stmt| $s₂]) | `([obj_stmt| if $e { $s₁ } else { $s₂ }]) => `(Stmt.ifElse [obj_expr| $e] [obj_stmt| $s₁] [obj_stmt| $s₂]) | `([obj_stmt| while $e { $s }]) => `(Stmt.whileLoop [obj_expr| $e] [obj_stmt| $s]) | `([obj_stmt| ($s:obj_stmt)]) => `([obj_stmt| $s]) end Spa