aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody <cody@codyq.dev>2023-06-28 14:28:54 -0500
committerCody <cody@codyq.dev>2023-06-28 14:28:54 -0500
commit9c915d3bf79078a2afd9c70ed8bbf606c3250f84 (patch)
treea7702cfa7b35e270b8be44b3566bcbf7a24d3cc2
parentda89b3f6cdf17dbaeba9aa25e22f1b8313f97536 (diff)
parent42b509365ce43e2f83475cbbc0f01bcd7b34fcd3 (diff)
downloadsloth-9c915d3bf79078a2afd9c70ed8bbf606c3250f84.tar.gz
Merge branch 'master' of github.com:slothlang/slothlang
-rwxr-xr-xbuild.sh2
-rwxr-xr-xcgolbin22096 -> 17184 bytes
-rw-r--r--examples/cgol.sloth2
-rw-r--r--sloth/src/analysis/setup.rs7
-rw-r--r--sloth/src/codegen/mod.rs24
-rw-r--r--sloth/src/parser/ast.rs9
-rw-r--r--sloth/src/parser/graph.rs23
-rw-r--r--sloth/src/parser/mod.rs2
-rw-r--r--sloth/src/parser/stmt.rs25
-rw-r--r--sloth/src/symtable.rs3
-rw-r--r--std/stdlib.c23
-rw-r--r--std/stdlib.sloth2
12 files changed, 115 insertions, 7 deletions
diff --git a/build.sh b/build.sh
index 62bd830..fe78ddf 100755
--- a/build.sh
+++ b/build.sh
@@ -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
diff --git a/cgol b/cgol
index 9a1335c..c614991 100755
--- a/cgol
+++ b/cgol
Binary files differ
diff --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;