diff options
| author | Cody <cody@codyq.dev> | 2023-06-28 14:28:54 -0500 |
|---|---|---|
| committer | Cody <cody@codyq.dev> | 2023-06-28 14:28:54 -0500 |
| commit | 9c915d3bf79078a2afd9c70ed8bbf606c3250f84 (patch) | |
| tree | a7702cfa7b35e270b8be44b3566bcbf7a24d3cc2 | |
| parent | da89b3f6cdf17dbaeba9aa25e22f1b8313f97536 (diff) | |
| parent | 42b509365ce43e2f83475cbbc0f01bcd7b34fcd3 (diff) | |
| download | sloth-9c915d3bf79078a2afd9c70ed8bbf606c3250f84.tar.gz | |
Merge branch 'master' of github.com:slothlang/slothlang
| -rwxr-xr-x | build.sh | 2 | ||||
| -rwxr-xr-x | cgol | bin | 22096 -> 17184 bytes | |||
| -rw-r--r-- | examples/cgol.sloth | 2 | ||||
| -rw-r--r-- | sloth/src/analysis/setup.rs | 7 | ||||
| -rw-r--r-- | sloth/src/codegen/mod.rs | 24 | ||||
| -rw-r--r-- | sloth/src/parser/ast.rs | 9 | ||||
| -rw-r--r-- | sloth/src/parser/graph.rs | 23 | ||||
| -rw-r--r-- | sloth/src/parser/mod.rs | 2 | ||||
| -rw-r--r-- | sloth/src/parser/stmt.rs | 25 | ||||
| -rw-r--r-- | sloth/src/symtable.rs | 3 | ||||
| -rw-r--r-- | std/stdlib.c | 23 | ||||
| -rw-r--r-- | std/stdlib.sloth | 2 |
12 files changed, 115 insertions, 7 deletions
@@ -1,5 +1,5 @@ # Build Sloth -cargo build +cargo build --features=llvm-sys/prefer-dynamic FILENAME="$1" # Compile standard library ./target/debug/sloth std/stdio.sloth std/stdlib.sloth std/stdmath.sloth $FILENAME Binary files differdiff --git a/examples/cgol.sloth b/examples/cgol.sloth index 4f7ea28..6cfe72d 100644 --- a/examples/cgol.sloth +++ b/examples/cgol.sloth @@ -105,7 +105,7 @@ fn main() Int { update(life, new); display(new); life = new; - wait(1.0); + wait(100); } return 0; } diff --git a/sloth/src/analysis/setup.rs b/sloth/src/analysis/setup.rs index 16ac100..1da3df7 100644 --- a/sloth/src/analysis/setup.rs +++ b/sloth/src/analysis/setup.rs @@ -134,6 +134,10 @@ pub(super) fn propagate_types_stmt(node: &mut Stmt) -> Result<(), AnalysisError> propagate_types(condition)?; propagate_types_stmt(body)?; } + StmtKind::ForStmt { iterator, identifier, body } => { + propagate_types(iterator)?; + propagate_types_stmt(body)?; + } StmtKind::DefineVariable { value, .. } => { propagate_types(value)?; } @@ -190,6 +194,9 @@ pub(super) fn propagate_types(node: &mut Expr) -> Result<(), AnalysisError> { AnalysisError::UnknownIdentifier(node.line, identifier.to_owned()), )? } + ExprKind::Iterator() => { + + } ExprKind::BinaryOp { lhs, rhs, op } => { // Propagating the types to the children propagate_types(lhs)?; diff --git a/sloth/src/codegen/mod.rs b/sloth/src/codegen/mod.rs index debc151..86e1ff0 100644 --- a/sloth/src/codegen/mod.rs +++ b/sloth/src/codegen/mod.rs @@ -151,6 +151,30 @@ impl<'ctx> Codegen<'ctx> { // Position the builder at the end of the loop self.builder.position_at_end(after_bb); } + StmtKind::ForStmt { iterator, identifier, body } => { + // Get the current function + let func = self.current_func.unwrap(); + + let loop_bb = self.context.append_basic_block(func, "loop"); + let body_bb = self.context.append_basic_block(func, "loop body"); + let after_bb = self.context.append_basic_block(func, "after loop"); + + self.builder.build_unconditional_branch(loop_bb); + + // Building the blocks for the head of the loop + self.builder.position_at_end(loop_bb); + let iterator = self.codegen_expr(iterator).unwrap().into_int_value(); + self.builder + .build_conditional_branch(iterator, body_bb, after_bb); + + // Building the blocks for the body of the loop + self.builder.position_at_end(body_bb); + self.codegen_stmt(body); + self.builder.build_unconditional_branch(loop_bb); + + // Position the builder at the end of the loop + self.builder.position_at_end(after_bb); + } StmtKind::DefineVariable { identifier, value, .. } => { diff --git a/sloth/src/parser/ast.rs b/sloth/src/parser/ast.rs index 00719e7..a676a9b 100644 --- a/sloth/src/parser/ast.rs +++ b/sloth/src/parser/ast.rs @@ -186,6 +186,10 @@ impl Stmt { children.push(condition.as_node()); children.push(body.as_node()); } + StmtKind::ForStmt { iterator, identifier, body} => { + children.push(iterator.as_node()); + children.push(body.as_node()); + } StmtKind::DefineVariable { value, .. } => children.push(value.as_node()), StmtKind::AssignVariable { value, .. } => children.push(value.as_node()), StmtKind::DefineFunction(Function { kind, .. }) => { @@ -215,6 +219,11 @@ pub enum StmtKind { condition: Expr, body: Box<Stmt>, }, + ForStmt { + iterator: Expr, + identifier: String, + body: Box<Stmt>, + }, DefineVariable { identifier: String, value: Expr, diff --git a/sloth/src/parser/graph.rs b/sloth/src/parser/graph.rs index 23f46fe..34c759f 100644 --- a/sloth/src/parser/graph.rs +++ b/sloth/src/parser/graph.rs @@ -72,6 +72,15 @@ impl GraphBuilder { self.traverse_expr0(condition)?; self.traverse_stmt0(body)?; } + StmtKind::ForStmt { iterator, identifier, body } => { + writeln!( + &mut self.graph, + "N{} [shape=box label=\"ForStmt\"];", + stmt.id + )?; + self.traverse_expr0(iterator)?; + self.traverse_stmt0(body)?; + } StmtKind::DefineVariable { identifier, value, @@ -240,6 +249,20 @@ impl GraphBuilder { self.traverse_expr(condition)?; self.traverse_stmt(body)?; } + StmtKind::ForStmt { iterator, identifier, body } => { + writeln!( + &mut self.graph, + "N{} -> N{} [label = \"Iterator\"];", + stmt.id, iterator.id + )?; + writeln!( + &mut self.graph, + "N{} -> N{} [label = \"Body\"];", + stmt.id, body.id + )?; + self.traverse_expr(iterator)?; + self.traverse_stmt(body)?; + } StmtKind::DefineVariable { value, .. } => { writeln!(&mut self.graph, "N{} -> N{};", stmt.id, value.id)?; self.traverse_expr(value)?; diff --git a/sloth/src/parser/mod.rs b/sloth/src/parser/mod.rs index 09a26fd..9bf4dd6 100644 --- a/sloth/src/parser/mod.rs +++ b/sloth/src/parser/mod.rs @@ -40,7 +40,7 @@ impl<'a> AstParser<'a> { let mut statements = Vec::new(); while !parser.eof() { statements.push(parser.statement()?); - } + } let root = Stmt::new( parser.reserve_id(), diff --git a/sloth/src/parser/stmt.rs b/sloth/src/parser/stmt.rs index 6af4634..4771abc 100644 --- a/sloth/src/parser/stmt.rs +++ b/sloth/src/parser/stmt.rs @@ -83,6 +83,31 @@ impl<'a> AstParser<'a> { )) } + fn for_stmt(&mut self) -> Result<Stmt, ParsingError> { + // Consume the for token + self.consume(TokenType::For, "Expected for")?; + + + let identifier = self.consume_identifier()?; + self.consume(TokenType::In, "Expected in")?; + let iterator = self.expression()?; + + let body = self.block()?; + + let kind = StmtKind::ForStmt { + iterator, + identifier, + body: body.into(), + }; + + Ok(Stmt::new( + self.reserve_id(), + self.line, + kind, + self.top.clone(), + )) + } + // TODO: Make variable types optional fn define_variable(&mut self) -> Result<Stmt, ParsingError> { // Consume the var token diff --git a/sloth/src/symtable.rs b/sloth/src/symtable.rs index eb3509a..549bb59 100644 --- a/sloth/src/symtable.rs +++ b/sloth/src/symtable.rs @@ -152,6 +152,9 @@ pub enum Type { Float, Boolean, String, + Iterator { + typ: Box<Type>, + }, Function { inputs: Vec<Type>, output: Box<Type>, diff --git a/std/stdlib.c b/std/stdlib.c index b70f5b7..dcb7ec3 100644 --- a/std/stdlib.c +++ b/std/stdlib.c @@ -1,9 +1,26 @@ -#include <unistd.h> +#include <errno.h> #include <stdlib.h> #include <string.h> +#include <time.h> -void wait(float x) { - sleep(x); +int wait(int msec) { + struct timespec ts; + int res; + + if (msec < 0) + { + errno = EINVAL; + return -1; + } + + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + + do { + res = nanosleep(&ts, &ts); + } while (res && errno == EINTR); + + return res; } int slen(char *str) { diff --git a/std/stdlib.sloth b/std/stdlib.sloth index eb6000d..ea57e45 100644 --- a/std/stdlib.sloth +++ b/std/stdlib.sloth @@ -1,4 +1,4 @@ -foreign fn wait(x: Float) Void; +foreign fn wait(x: Int) Int; foreign fn print(str: String) Void; foreign fn slen(str: String) Int; # foreign fn charAt(str: String) Char; |
