Beginnings of loops

This commit is contained in:
Dane Johnson 2024-11-16 13:44:04 -06:00
parent 5fdd28fe0e
commit 7213f4a487
7 changed files with 41 additions and 12 deletions

View File

@ -2,12 +2,6 @@
(add-to-list 'auto-mode-alist '("\\.dee\\'" . dee-mode)) (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 (defcustom dee-indent-offset 4
"Default indentation offset for Deelang." "Default indentation offset for Deelang."
:group 'dee :group 'dee
@ -34,14 +28,14 @@
(defvar dee-font-lock-keywords (defvar dee-font-lock-keywords
`(,(rx symbol-start `(,(rx symbol-start
(or (or
"if" "elif" "else" "") "if" "elif" "else" "loop" "until" "over" "in" "")
symbol-end) symbol-end)
(,(rx (group (regexp dee-font-lock-id-re)) (* space) "<-") (,(rx (group (regexp dee-font-lock-id-re)) (* space) "<-")
(1 font-lock-variable-name-face)) (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) "(") (,(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 () (defun dee-indent-line-function ()
'noindent) ;TODO 'noindent) ;TODO

View File

@ -8,7 +8,7 @@ foo <- ->
bar() bar()
baz() baz()
# functions with block statements # functions with block statements
oo <- x -> y -> x * y + 7 ## Multiple argument functions foo <- x -> y -> x * y + 7 ## Multiple argument functions
if test?() if test?()
do-something() do-something()
elif other-test?() elif other-test?()
@ -23,3 +23,8 @@ else
if second-test?() if second-test?()
do-a-real-bad-thing() do-a-real-bad-thing()
## Nested blocks ## Nested blocks
i <- 1
loop until i > 10
print(i)
i <- 1

View File

@ -3,6 +3,7 @@ program := __* stmt*
stmt := assignment / stmt := assignment /
funcall stop / funcall stop /
conditional / conditional /
loop /
expr stop expr stop
expr := - _ expr / expr := - _ expr /
@ -31,6 +32,10 @@ if := "if" _ expr block
elif := "elif" _ expr block elif := "elif" _ expr block
else := "else" _ block else := "else" _ block
loop := "loop" _ (until / over / block)
until := "until" _ expr block
over := "over"_ id "in" _ expr block
block := expr / indented_block block := expr / indented_block
indented_block := stop indent __* stmt+ dedent indented_block := stop indent __* stmt+ dedent

View File

@ -107,6 +107,7 @@ pub fn emit(w: &mut dyn Write, stmt: &parser::Stmt, ctx: &mut LexicalContext) ->
writeln!(w, "}}")?; writeln!(w, "}}")?;
} }
} }
parser::Stmt::Loop(_) => todo!()
} }
Ok(()) Ok(())
} }

3
src/internal.rs Normal file
View File

@ -0,0 +1,3 @@
//! Internal compiler steps, expansion, cps, optimization.

View File

@ -1,6 +1,7 @@
mod parser; mod parser;
mod evaluator; mod evaluator;
mod emitter; mod emitter;
mod internal;
use clap::Parser; use clap::Parser;

View File

@ -5,6 +5,7 @@ pub enum Stmt {
Assignment(String, Expr), Assignment(String, Expr),
Funcall(Expr), Funcall(Expr),
Conditional(Vec<GuardedBlock>, Option<Block>), Conditional(Vec<GuardedBlock>, Option<Block>),
Loop(Loop),
BareExpr(Expr), BareExpr(Expr),
} }
@ -49,6 +50,13 @@ pub struct GuardedBlock {
pub block: Block, pub block: Block,
} }
#[derive(Debug,PartialEq,Clone)]
pub enum Loop {
Bare(Block),
Until(GuardedBlock),
Over(String, Expr, Block),
}
peg::parser! { peg::parser! {
grammar deelang_parser() for str { grammar deelang_parser() for str {
pub rule program() -> Vec<Stmt> pub rule program() -> Vec<Stmt>
@ -57,6 +65,7 @@ peg::parser! {
= a:assignment() { a } / = a:assignment() { a } /
f:funcall() stop() { Stmt::Funcall(f) } / f:funcall() stop() { Stmt::Funcall(f) } /
c:conditional() { c } / c:conditional() { c } /
l:_loop() { Stmt::Loop(l) } /
e:expr() stop() { Stmt::BareExpr(e) } e:expr() stop() { Stmt::BareExpr(e) }
rule expr() -> Expr = precedence! { rule expr() -> Expr = precedence! {
e1:(@) "=" _ e2:@ { Expr::Equal(Box::new(e1), Box::new(e2)) } e1:(@) "=" _ e2:@ { Expr::Equal(Box::new(e1), Box::new(e2)) }
@ -114,6 +123,17 @@ peg::parser! {
} }
rule _else() -> Block rule _else() -> Block
= "else" _ b:block() { b } = "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 rule block() -> Block
= i:indented_block() { i } / = i:indented_block() { i } /
e:expr() { vec![Stmt::BareExpr(e)] } e:expr() { vec![Stmt::BareExpr(e)] }