Skip to content

Commit

Permalink
Merge pull request #519 from bvssvni/in
Browse files Browse the repository at this point in the history
Added for-in loop for in-types
  • Loading branch information
bvssvni authored Jun 13, 2018
2 parents e530a9c + 06b4fb6 commit a18e57f
Show file tree
Hide file tree
Showing 15 changed files with 300 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dyon"
version = "0.34.1"
version = "0.35.0"
authors = ["Sven Nilsen <bvssvni@gmail.com>"]
keywords = ["script", "scripting", "game", "language", "piston"]
description = "A rusty dynamically typed scripting language"
Expand Down
30 changes: 16 additions & 14 deletions assets/syntax.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ _seps: "(){}[],.:;=<>*·+-/%^?~|&∧∨!¬∑∃∀\n\"\\"
object:"object"
arr
["return" wn expr:"return"]
for_in:"for_in"
for_n:"for_n"
for:"for"
loop:"loop"
Expand Down Expand Up @@ -111,24 +112,25 @@ _seps: "(){}[],.:;=<>*·+-/%^?~|&∧∨!¬∑∃∀\n\"\\"
expr:"cond" ?w ";" ?w
expr:"step" ?w block:"block"]
36 for_n = [label "for" short_body]
37 loop = [label "loop" .w! block:"block"]
38 break = ["break" ?w ?["'" .._seps!:"label"]]
39 continue = ["continue" ?w ?["'" .._seps!:"label"]]
40 if = ["if" .w! expr:"cond" ?w block:"true_block"
37 for_in = [label "for" .w! .._seps!:"name" .w! "in" .w! expr:"iter" ?w block:"block"]
38 loop = [label "loop" .w! block:"block"]
39 break = ["break" ?w ?["'" .._seps!:"label"]]
40 continue = ["continue" ?w ?["'" .._seps!:"label"]]
41 if = ["if" .w! expr:"cond" ?w block:"true_block"
.r?([?w "else" w "if" ?w expr:"else_if_cond" ?w block:"else_if_block"])
?[?w "else" ?w block:"else_block"]]
41 call = [?[.._seps!:"alias" "::"] .._seps!:"name" wn "(" ?w
42 call = [?[.._seps!:"alias" "::"] .._seps!:"name" wn "(" ?w
.s?.(, arg_expr:"call_arg") ?w ")"]
42 named_call = [?[.._seps!:"alias" "::"] .._seps!:"word" wn "(" ?w
43 named_call = [?[.._seps!:"alias" "::"] .._seps!:"word" wn "(" ?w
.s?.(, [.._seps!:"word" ?w ":" ?w arg_expr:"call_arg" ?w]) ")"]
43 go = ["go " ?w {call:"call" named_call:"named_call"}]
44 assign = [lexpr:"left" ?w assign_op ?w expr:"right"]
45 assign_op = {":=":":=" "=":"=" "+=":"+=" "-=":"-=" "*=":"*=" "/=":"/=" "%=":"%="}
46 compare = [lexpr:"left" ?w compare_op ?w expr:"right"]
47 compare_op = {"==":"==" "!=":"!=" "¬=":"!=" "<=":"<=" "<":"<" ">=":">=" ">":">"}
48 grab = ["grab" ?[w "'" .$:"grab_level"] w expr:"expr"]
49 try_expr = ["try" w expr:"expr"]
50 in = ["in" w ?[.._seps!:"alias" "::"] .._seps!:"name"]
44 go = ["go " ?w {call:"call" named_call:"named_call"}]
45 assign = [lexpr:"left" ?w assign_op ?w expr:"right"]
46 assign_op = {":=":":=" "=":"=" "+=":"+=" "-=":"-=" "*=":"*=" "/=":"/=" "%=":"%="}
47 compare = [lexpr:"left" ?w compare_op ?w expr:"right"]
48 compare_op = {"==":"==" "!=":"!=" "¬=":"!=" "<=":"<=" "<":"<" ">=":">=" ">":">"}
49 grab = ["grab" ?[w "'" .$:"grab_level"] w expr:"expr"]
50 try_expr = ["try" w expr:"expr"]
51 in = ["in" w ?[.._seps!:"alias" "::"] .._seps!:"name"]

60 label = ?["'" .._seps!:"label" ?w ":" ?w]
61 short_body = [.w! .s!.(, [.._seps!:"name" ?w
Expand Down
4 changes: 2 additions & 2 deletions interactive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "piston-dyon_interactive"
version = "0.20.0"
version = "0.21.0"
authors = ["Sven Nilsen <bvssvni@gmail.com>"]
description = "A library for interactive coding with the Piston game engine"
keywords = ["script", "scripting", "game", "language", "piston"]
Expand All @@ -12,7 +12,7 @@ homepage = "https://github.com/pistondevelopers/dyon/interactive"
name = "dyon_interactive"

[dependencies.dyon]
version = "0.34.0"
version = "0.35.0"
path = ".."

[dependencies]
Expand Down
24 changes: 24 additions & 0 deletions source/syntax/for_in.dyon
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
fn log(a: f64) {}

fn finish() {}

fn bar(id: f64, n: f64) -> bool {
for i n {
log((id + 1) * 1000 + i)
sleep(0.1)
}
finish()
return true
}

fn main() {
log := in log
finish := in finish
n := 10
for i n {_ := go bar(i, 2)}
loop {
for msg in log {println(msg[0])}
if n == 0 {break}
for done in finish {n -= 1}
}
}
25 changes: 21 additions & 4 deletions source/test.dyon
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
fn log(a: f64) {}

fn finish() {}

fn bar(id: f64, n: f64) -> bool {
for i n {
log((id + 1) * 1000 + i)
sleep(0.1)
}
finish()
return true
}

fn main() {
start := now()
for i 10000000 {
a := grab link {1 2 3 4 5 7 8 9 0909 09}
log := in log
finish := in finish
n := 10
for i n {_ := go bar(i, 2)}
loop {
for msg in log {println(msg[0])}
if n == 0 {break}
for done in finish {n -= 1}
}
println(now() - start)
}
4 changes: 4 additions & 0 deletions src/ast/infer_len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ fn infer_expr(
ForN(ref for_n_expr) => {
return infer_for_n(for_n_expr, name, decls)
}
ForIn(ref for_in_expr) => {
let res = infer_expr(&for_in_expr.iter, name, decls);
if res.is_some() { return res; }
}
Sum(ref for_n_expr) => {
return infer_for_n(for_n_expr, name, decls)
}
Expand Down
83 changes: 83 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,7 @@ pub enum Expression {
Vec4(Vec4),
For(Box<For>),
ForN(Box<ForN>),
ForIn(Box<ForIn>),
Sum(Box<ForN>),
SumVec4(Box<ForN>),
Prod(Box<ForN>),
Expand Down Expand Up @@ -995,6 +996,10 @@ impl Expression {
file, source, convert, ignored) {
convert.update(range);
result = Some(Expression::For(Box::new(val)));
} else if let Ok((range, val)) = ForIn::from_meta_data(
file, source, "for_in", convert, ignored) {
convert.update(range);
result = Some(Expression::ForIn(Box::new(val)));
} else if let Ok((range, val)) = ForN::from_meta_data(
file, source, "for_n", convert, ignored) {
convert.update(range);
Expand Down Expand Up @@ -1132,6 +1137,7 @@ impl Expression {
Vec4(ref vec4) => vec4.source_range,
For(ref for_expr) => for_expr.source_range,
ForN(ref for_n_expr) => for_n_expr.source_range,
ForIn(ref for_in_expr) => for_in_expr.source_range,
Sum(ref for_n_expr) => for_n_expr.source_range,
SumVec4(ref for_n_expr) => for_n_expr.source_range,
Prod(ref for_n_expr) => for_n_expr.source_range,
Expand Down Expand Up @@ -1202,6 +1208,8 @@ impl Expression {
for_expr.resolve_locals(relative, stack, closure_stack, module, use_lookup),
ForN(ref for_n_expr) =>
for_n_expr.resolve_locals(relative, stack, closure_stack, module, use_lookup),
ForIn(ref for_n_expr) =>
for_n_expr.resolve_locals(relative, stack, closure_stack, module, use_lookup),
Sum(ref for_n_expr) =>
for_n_expr.resolve_locals(relative, stack, closure_stack, module, use_lookup),
SumVec4(ref for_n_expr) =>
Expand Down Expand Up @@ -3170,6 +3178,81 @@ impl For {
}
}

#[derive(Debug, Clone)]
pub struct ForIn {
pub name: Arc<String>,
pub iter: Expression,
pub block: Block,
pub label: Option<Arc<String>>,
pub source_range: Range,
}

impl ForIn {
pub fn from_meta_data(
file: &Arc<String>,
source: &Arc<String>,
node: &str,
mut convert: Convert,
ignored: &mut Vec<Range>)
-> Result<(Range, ForIn), ()> {
let start = convert.clone();
let start_range = try!(convert.start_node(node));
convert.update(start_range);

let mut name: Option<Arc<String>> = None;
let mut iter: Option<Expression> = None;
let mut block: Option<Block> = None;
let mut label: Option<Arc<String>> = None;
loop {
if let Ok(range) = convert.end_node(node) {
convert.update(range);
break;
} else if let Ok((range, val)) = convert.meta_string("name") {
convert.update(range);
name = Some(val);
} else if let Ok((range, val)) = Expression::from_meta_data(
file, source, "iter", convert, ignored) {
convert.update(range);
iter = Some(val);
} else if let Ok((range, val)) = Block::from_meta_data(
file, source, "block", convert, ignored) {
convert.update(range);
block = Some(val);
} else if let Ok((range, val)) = convert.meta_string("label") {
convert.update(range);
label = Some(val);
} else {
let range = convert.ignore();
convert.update(range);
ignored.push(range);
}
}

let name = try!(name.ok_or(()));
let iter = try!(iter.ok_or(()));
let block = try!(block.ok_or(()));
Ok((convert.subtract(start), ForIn {
name, iter, block, label,
source_range: convert.source(start).unwrap(),
}))
}

pub fn resolve_locals(
&self, relative: usize,
stack: &mut Vec<Option<Arc<String>>>,
closure_stack: &mut Vec<usize>,
module: &Module,
use_lookup: &UseLookup,
) {
let st = stack.len();
self.iter.resolve_locals(relative, stack, closure_stack, module, use_lookup);
stack.truncate(st);
stack.push(Some(self.name.clone()));
self.block.resolve_locals(relative, stack, closure_stack, module, use_lookup);
stack.truncate(st);
}
}

#[derive(Debug, Clone)]
pub struct ForN {
pub name: Arc<String>,
Expand Down
10 changes: 10 additions & 0 deletions src/ast/replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use super::{
Expression,
For,
ForN,
ForIn,
Go,
Id,
If,
Expand Down Expand Up @@ -175,6 +176,15 @@ pub fn number(expr: &Expression, name: &Arc<String>, val: f64) -> Expression {
}))
}
}
E::ForIn(ref for_in_expr) => {
E::ForIn(Box::new(ForIn {
label: for_in_expr.label.clone(),
name: for_in_expr.name.clone(),
iter: number(&for_in_expr.iter, name, val),
block: number_block(&for_in_expr.block, name, val),
source_range: for_in_expr.source_range,
}))
}
E::ForN(ref for_n_expr) => {
E::ForN(Box::new(number_for_n(for_n_expr, name, val)))
}
Expand Down
15 changes: 15 additions & 0 deletions src/grab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,21 @@ pub fn grab_expr(
source_range: for_expr.source_range.clone(),
}))), Flow::Continue))
}
&E::ForIn(ref for_in_expr) => {
Ok((Grabbed::Expression(E::ForIn(Box::new(ast::ForIn {
name: for_in_expr.name.clone(),
iter: match grab_expr(level, rt, &for_in_expr.iter, side, module) {
Ok((Grabbed::Expression(x), Flow::Continue)) => x,
x => return x,
},
block: match grab_block(level, rt, &for_in_expr.block, side, module) {
Ok((Grabbed::Block(x), Flow::Continue)) => x,
x => return x,
},
label: for_in_expr.label.clone(),
source_range: for_in_expr.source_range.clone(),
}))), Flow::Continue))
}
&E::Swizzle(ref swizzle) => {
Ok((Grabbed::Expression(E::Swizzle(Box::new(ast::Swizzle {
sw0: swizzle.sw0.clone(),
Expand Down
4 changes: 4 additions & 0 deletions src/lifetime/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub enum Kind {
KeyValue,
For,
ForN,
ForIn,
Sum,
SumVec4,
Prod,
Expand All @@ -46,6 +47,7 @@ pub enum Kind {
End,
Init,
Cond,
Iter,
ElseIfCond,
ElseIfBlock,
Step,
Expand Down Expand Up @@ -124,6 +126,7 @@ impl Kind {
"key_value" => Kind::KeyValue,
"for" => Kind::For,
"for_n" => Kind::ForN,
"for_in" => Kind::ForIn,
"sum" => Kind::Sum,
"sum_vec4" => Kind::SumVec4,
"prod" => Kind::Prod,
Expand All @@ -138,6 +141,7 @@ impl Kind {
"end" => Kind::End,
"init" => Kind::Init,
"cond" => Kind::Cond,
"iter" => Kind::Iter,
"else_if_cond" => Kind::ElseIfCond,
"else_if_block" => Kind::ElseIfBlock,
"step" => Kind::Step,
Expand Down
3 changes: 2 additions & 1 deletion src/lifetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ pub fn check(

'search: loop {
if nodes[parent].kind.is_decl_loop() ||
nodes[parent].kind.is_decl_un_loop() {
nodes[parent].kind.is_decl_un_loop() ||
nodes[parent].kind == Kind::ForIn {
let my_name = nodes[i].name().unwrap();
for name in &nodes[parent].names {
if name == my_name {
Expand Down
3 changes: 2 additions & 1 deletion src/lifetime/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl Node {
match self.kind {
Pow | Sum | Prod | SumVec4 | Min | Max | Any | All |
Vec4 | Vec4UnLoop | Swizzle |
Assign | For | ForN | Link | LinkFor |
Assign | For | ForN | ForIn | Link | LinkFor |
Closure | CallClosure | Grab | TryExpr | Norm | In => false,
Add | Mul | Compare => self.children.len() == 1,
_ => true
Expand Down Expand Up @@ -167,6 +167,7 @@ impl Node {
(_, Kind::Go) => {}
(_, Kind::For) => {}
(_, Kind::ForN) => {}
(_, Kind::ForIn) => {}
(_, Kind::Break) => {}
(_, Kind::Continue) => {}
(_, Kind::Sift) => {}
Expand Down
Loading

0 comments on commit a18e57f

Please sign in to comment.