From 7213f4a4870fb0e47ba0fa0cd587658e744614c8 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Sat, 16 Nov 2024 13:44:04 -0600 Subject: [PATCH] Beginnings of loops --- dee-mode.el | 14 ++++---------- demo/buildup.dee | 7 ++++++- peg.txt | 7 ++++++- src/emitter.rs | 1 + src/internal.rs | 3 +++ src/main.rs | 1 + src/parser.rs | 20 ++++++++++++++++++++ 7 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 src/internal.rs diff --git a/dee-mode.el b/dee-mode.el index 6b41fd4..bc3389a 100644 --- a/dee-mode.el +++ b/dee-mode.el @@ -2,12 +2,6 @@ (add-to-list 'auto-mode-alist '("\\.dee\\'" . dee-mode)) -(defface dee-function-param-face - '((t . (:slant italic - :weight bold - :foreground "orange"))) - "A face to help identify function parameter in Deelang.") - (defcustom dee-indent-offset 4 "Default indentation offset for Deelang." :group 'dee @@ -34,14 +28,14 @@ (defvar dee-font-lock-keywords `(,(rx symbol-start (or - "if" "elif" "else" "") + "if" "elif" "else" "loop" "until" "over" "in" "") symbol-end) (,(rx (group (regexp dee-font-lock-id-re)) (* space) "<-") (1 font-lock-variable-name-face)) - (,(rx (group (regexp dee-font-lock-id-re)) (* space) "->") - (1 'dee-function-param-face)) (,(rx (group (regexp dee-font-lock-id-re)) (* space) "(") - (1 font-lock-function-name-face)))) + (1 font-lock-function-name-face)) + (,(rx (group (regexp dee-font-lock-id-re)) (* space) "->") + (1 font-lock-constant-face)))) (defun dee-indent-line-function () 'noindent) ;TODO diff --git a/demo/buildup.dee b/demo/buildup.dee index b86ea26..d98ba0d 100644 --- a/demo/buildup.dee +++ b/demo/buildup.dee @@ -8,7 +8,7 @@ foo <- -> bar() baz() # functions with block statements -oo <- x -> y -> x * y + 7 ## Multiple argument functions +foo <- x -> y -> x * y + 7 ## Multiple argument functions if test?() do-something() elif other-test?() @@ -23,3 +23,8 @@ else if second-test?() do-a-real-bad-thing() ## Nested blocks + +i <- 1 +loop until i > 10 + print(i) + i <- 1 diff --git a/peg.txt b/peg.txt index b42f97f..3835a24 100644 --- a/peg.txt +++ b/peg.txt @@ -2,7 +2,8 @@ program := __* stmt* stmt := assignment / funcall stop / - conditional / + conditional / + loop / expr stop expr := - _ expr / @@ -31,6 +32,10 @@ if := "if" _ expr block elif := "elif" _ expr block else := "else" _ block +loop := "loop" _ (until / over / block) +until := "until" _ expr block +over := "over"_ id "in" _ expr block + block := expr / indented_block indented_block := stop indent __* stmt+ dedent diff --git a/src/emitter.rs b/src/emitter.rs index a00dc7c..d207607 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -107,6 +107,7 @@ pub fn emit(w: &mut dyn Write, stmt: &parser::Stmt, ctx: &mut LexicalContext) -> writeln!(w, "}}")?; } } + parser::Stmt::Loop(_) => todo!() } Ok(()) } diff --git a/src/internal.rs b/src/internal.rs new file mode 100644 index 0000000..18443ec --- /dev/null +++ b/src/internal.rs @@ -0,0 +1,3 @@ +//! Internal compiler steps, expansion, cps, optimization. + + diff --git a/src/main.rs b/src/main.rs index 96b078e..facf6d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod parser; mod evaluator; mod emitter; +mod internal; use clap::Parser; diff --git a/src/parser.rs b/src/parser.rs index be6daa2..4876ddc 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -5,6 +5,7 @@ pub enum Stmt { Assignment(String, Expr), Funcall(Expr), Conditional(Vec, Option), + Loop(Loop), BareExpr(Expr), } @@ -49,6 +50,13 @@ pub struct GuardedBlock { pub block: Block, } +#[derive(Debug,PartialEq,Clone)] +pub enum Loop { + Bare(Block), + Until(GuardedBlock), + Over(String, Expr, Block), +} + peg::parser! { grammar deelang_parser() for str { pub rule program() -> Vec @@ -57,6 +65,7 @@ peg::parser! { = a:assignment() { a } / f:funcall() stop() { Stmt::Funcall(f) } / c:conditional() { c } / + l:_loop() { Stmt::Loop(l) } / e:expr() stop() { Stmt::BareExpr(e) } rule expr() -> Expr = precedence! { e1:(@) "=" _ e2:@ { Expr::Equal(Box::new(e1), Box::new(e2)) } @@ -114,6 +123,17 @@ peg::parser! { } rule _else() -> Block = "else" _ b:block() { b } + rule _loop() -> Loop + = "loop" _ "until" _ e:expr() b:block() __* { + Loop::Until(GuardedBlock{ + guard:e, + block: b, + }) + } / + "loop" _ "over" _ i:id() "in" _ e:expr() b:block() __* { + Loop::Over(i, e, b) + } / + "loop" _ b:block() __* { Loop::Bare(b) } rule block() -> Block = i:indented_block() { i } / e:expr() { vec![Stmt::BareExpr(e)] }