aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh2
-rw-r--r--examples/cgol.sloth42
-rw-r--r--examples/mandelbrot.sloth48
-rw-r--r--mandelbrot.c32
-rw-r--r--mandelbrot.java40
-rw-r--r--mandelbrot.py23
-rw-r--r--sloth/src/analysis/setup.rs11
-rw-r--r--sloth/src/codegen/mod.rs6
-rw-r--r--sloth/src/parser/ast.rs2
-rw-r--r--sloth/src/parser/graph.rs4
-rw-r--r--sloth/src/parser/stmt.rs23
11 files changed, 181 insertions, 52 deletions
diff --git a/build.sh b/build.sh
index 5c6c414..e1794ae 100755
--- a/build.sh
+++ b/build.sh
@@ -2,7 +2,7 @@
cargo build
FILENAME="$1"
# Compile standard library
-./target/debug/sloth std/stdio.sloth std/stdlib.sloth std/stdmath.sloth $FILENAME
+./target/release/sloth std/stdio.sloth std/stdlib.sloth std/stdmath.sloth $FILENAME
# Generate binary
clang output.o std/stdio.c std/stdlib.c std/stdmath.c -o "${FILENAME%.sloth}"
diff --git a/examples/cgol.sloth b/examples/cgol.sloth
index 6cfe72d..4021e58 100644
--- a/examples/cgol.sloth
+++ b/examples/cgol.sloth
@@ -5,7 +5,7 @@ fn populate() [Int] {
# Fill the vector with random values
var i: Int = 0;
- while i < 2500 {
+ while i < 57600 {
var n: Int = randGen(0,1);
vpushi(life, n);
i = i+1;
@@ -18,7 +18,7 @@ fn coord(x: Int, y: Int) Int {
var res: Int = -1;
# Calculate index based on coordinates
if x >= 0 && y >= 0 {
- res = y*50 + x;
+ res = y*240+ x;
}
# if coordinate is invalid, return -1
return res;
@@ -37,9 +37,9 @@ fn cval(x: Int, y: Int, life: [Int]) Int {
fn update(life: [Int], new: [Int]) {
# Iterate through life
var x: Int = 0;
- while x < 50 {
+ while x < 64 {
var y: Int = 0;
- while y < 50 {
+ while y < 240 {
# Calculate total score around selected cell
var total: Int =
cval(x-1, y-1, life) + # Top Left
@@ -77,20 +77,30 @@ fn update(life: [Int], new: [Int]) {
fn display(life: [Int]) {
# Iterate through life
#termclear();
- var x: Int = 0;
- while x < 50 {
- var y: Int = 0;
- while y < 50 {
- # if the cell is alive, print
- termpos(x, y);
- if cval(x, y, life) == 1{
- print("#");
+ #var x: Int = 0;
+ #while x < 59 {
+ # var y: Int = 0;
+ # while y < 240 {
+ # # if the cell is alive, print
+ # termpos(x, y);
+ # if cval(x, y, life) == 1{
+ # print("█");
+ # } else {
+ # print(" ");
+ # }
+ # y = y+1;
+ # }
+ # x = x+1;
+ #}
+ for x in 3..62 {
+ for y in 0..240 {
+ termpos(x-3, y);
+ if cval(x-3, y, life) == 1 {
+ print("█");
} else {
- print(" ");
- }
- y = y+1;
+ print(" ");
+ }
}
- x = x+1;
}
}
diff --git a/examples/mandelbrot.sloth b/examples/mandelbrot.sloth
index 391e86e..c52f5de 100644
--- a/examples/mandelbrot.sloth
+++ b/examples/mandelbrot.sloth
@@ -1,32 +1,35 @@
-#foreign fn print(str: String);
-#foreign fn printint(i: Int);
-#foreign fn as_int(x: Float) Int;
+fn main() Int {
+ # Configuration related variables
+ var size: Float = 800.0;
+ var maxVal = 4.0;
+ var maxIter = 50.0;
+ var plane = 4.0;
-#foreign fn termpos(x: Int, y: Int) Void;
-
-fn main() Int{
- var size: Float = 1000.0;
- var maxVal: Float = 4.0;
- var maxIter: Float = 50.0;
- var plane: Float = 4.0;
- var x: Float = 0.0;
+ # Loop over X the configured size
+ var x = 0.0;
while x < size {
- var y: Float = 0.0;
+ # Loop over Y for the configured size
+ var y = 0.0;
while y < size {
- var cReal: Float = (x * plane / size) - 2.0;
- var cImg: Float = (y * plane / size) - 2.0;
- var zReal: Float = 0.0;
- var zImg: Float = 0.0;
- var count: Float = 0.0;
+ # Get variables ready
+ var cReal = (x * plane / size) - 2.0;
+ var cImg = (y * plane / size) - 2.0;
+ var zReal = 0.0;
+ var zImg = 0.0;
+ var count = 0.0;
+
+ # Loop over and finish mandelbrot calculations
while (zReal * zReal + zImg * zImg) <= maxVal && count < maxIter {
- var temp: Float = (zReal * zReal) - (zImg * zImg) + cReal;
+ var temp = (zReal * zReal) - (zImg * zImg) + cReal;
zImg = 2.0 * zReal * zImg + cImg;
zReal = temp;
count = count + 1.0;
- }
- if as_int(count) == as_int(maxIter) {
- termpos(as_int(x), as_int(y));
- print("*");
+
+ # Display the mandelbrot to the actual screen
+ if as_int(count) == as_int(maxIter) {
+ termpos(as_int(x), as_int(y));
+ print("█");
+ }
}
y = y + 1.0;
}
@@ -34,3 +37,4 @@ fn main() Int{
}
return 0;
}
+
diff --git a/mandelbrot.c b/mandelbrot.c
new file mode 100644
index 0000000..a6eff9e
--- /dev/null
+++ b/mandelbrot.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main() {
+ float size = 800.0;
+ float maxVal = 4.0;
+ float maxIter = 50.0;
+ float plane = 4.0;
+ int x = 0;
+ while (x < size) {
+ int y = 0;
+ while (y < size) {
+ float cReal = (x * plane / size) - 2.0;
+ float cImg = (y * plane / size) - 2.0;
+ float zReal = 0.0;
+ float zImg = 0.0;
+ float count = 0.0;
+ while ((zReal * zReal + zImg * zImg) <= maxVal && count < maxIter) {
+ float temp = (zReal * zReal) - (zImg * zImg) + cReal;
+ zImg = 2.0 * zReal * zImg + cImg;
+ zReal = temp;
+ count = count + 1;
+ if (count == maxIter) {
+ printf("\x1b[%d;%dH", x, y);
+ printf("█");
+ }
+ }
+ y = y + 1;
+ }
+ x = x + 1;
+ }
+ return 0;
+}
diff --git a/mandelbrot.java b/mandelbrot.java
new file mode 100644
index 0000000..1409ce6
--- /dev/null
+++ b/mandelbrot.java
@@ -0,0 +1,40 @@
+public class mandelbrot {
+ public static void main(String[] args) {
+ // char escCode = 0x1B;
+ // System.out.printf("%c[%d;%dH", escCode, 20, 10);
+ // System.out.print("█");
+ // System.out.printf("%c[%d;%dH", escCode, 20, 20);
+ // System.out.print("█");
+ // System.out.printf("%c[%d;%dH", escCode, 30, 10);
+ // System.out.print("█");
+
+ double size = 800;
+ double maxVal = 4;
+ double maxIter = 50;
+ double plane = 4;
+ int x = 0;
+ while (x < size) {
+ int y = 0;
+ while (y < size) {
+ double cReal = (x * plane / size) - 2.0;
+ double cImg = (y * plane / size) - 2.0;
+ double zReal = 0.0;
+ double zImg = 0.0;
+ double count = 0.0;
+ while ((zReal * zReal + zImg * zImg) <= maxVal && count < maxIter) {
+ var temp = (zReal * zReal) - (zImg * zImg) + cReal;
+ zImg = 2.0 * zReal * zImg + cImg;
+ zReal = temp;
+ count = count + 1.0;
+ if (count == maxIter) {
+ char escCode = 0x1B;
+ System.out.printf("%c[%d;%dH", escCode, x, y);
+ System.out.print("█");
+ }
+ }
+ y = y + 1;
+ }
+ x = x + 1;
+ }
+ }
+}
diff --git a/mandelbrot.py b/mandelbrot.py
new file mode 100644
index 0000000..234beb4
--- /dev/null
+++ b/mandelbrot.py
@@ -0,0 +1,23 @@
+size = 800.0
+maxVal = 4.0
+maxIter = 50.0
+plane = 4.0
+x = 0;
+while x < size:
+ y = 0;
+ while y < size:
+ cReal = (x * plane / size) - 2.0
+ cImg = (y * plane / size) - 2.0
+ zReal = 0.0
+ zImg = 0.0
+ count = 0.0
+ while (zReal * zReal + zImg * zImg) <= maxVal and count < maxIter:
+ temp = (zReal * zReal) - (zImg * zImg) + cReal
+ zImg = 2.0 * zReal * zImg + cImg
+ zReal = temp
+ count = count + 1.0
+ if count == maxIter:
+ print(f"\x1b[{x};{y}H", end="")
+ print("█", end="")
+ y = y + 1
+ x = x + 1
diff --git a/sloth/src/analysis/setup.rs b/sloth/src/analysis/setup.rs
index 274ec4a..165051a 100644
--- a/sloth/src/analysis/setup.rs
+++ b/sloth/src/analysis/setup.rs
@@ -28,7 +28,14 @@ impl Populator {
identifier, typ, ..
} => {
// When a variable is defined add it to the symbol table of the current scope.
- let symbol = self.build_value_symbol(node.line(), &table, typ)?;
+ let symbol = self.build_value_symbol(
+ node.line(),
+ &table,
+ &typ.clone().unwrap_or(TypeIdentifier {
+ name: "Float".to_owned(),
+ is_list: false,
+ }),
+ )?;
table.insert(identifier.to_owned(), symbol);
}
StmtKind::DefineFunction(Function {
@@ -151,7 +158,7 @@ pub(super) fn propagate_types_stmt(node: &mut Stmt) -> Result<(), AnalysisError>
propagate_types(iterator)?;
propagate_types_stmt(body)?;
}
- StmtKind::DefineVariable { value, .. } => {
+ StmtKind::DefineVariable { value, typ, .. } => {
propagate_types(value)?;
}
StmtKind::AssignVariable { value, .. } => {
diff --git a/sloth/src/codegen/mod.rs b/sloth/src/codegen/mod.rs
index 65277e7..0452b03 100644
--- a/sloth/src/codegen/mod.rs
+++ b/sloth/src/codegen/mod.rs
@@ -511,7 +511,7 @@ impl<'ctx> Codegen<'ctx> {
.builder
.build_array_malloc(
element_type,
- i32_type.const_int(5000, false),
+ i32_type.const_int(57600, false),
"vecinnerptr",
)
.unwrap();
@@ -559,7 +559,7 @@ impl<'ctx> Codegen<'ctx> {
.build_store(size_ptr, i32_type.const_int(values.len() as u64, false));
self.builder
- .build_store(cap_ptr, i32_type.const_int(2500, false));
+ .build_store(cap_ptr, i32_type.const_int(57600, false));
self.builder.build_store(inner, inner_ptr);
@@ -652,7 +652,7 @@ impl<'ctx> Codegen<'ctx> {
&triple,
"x86-64",
"",
- OptimizationLevel::None,
+ OptimizationLevel::Aggressive,
RelocMode::Default,
CodeModel::Default,
)
diff --git a/sloth/src/parser/ast.rs b/sloth/src/parser/ast.rs
index 089a362..fbd0970 100644
--- a/sloth/src/parser/ast.rs
+++ b/sloth/src/parser/ast.rs
@@ -231,7 +231,7 @@ pub enum StmtKind {
DefineVariable {
identifier: String,
value: Expr,
- typ: TypeIdentifier,
+ typ: Option<TypeIdentifier>,
},
AssignVariable {
identifier: String,
diff --git a/sloth/src/parser/graph.rs b/sloth/src/parser/graph.rs
index dde7481..3d0dca5 100644
--- a/sloth/src/parser/graph.rs
+++ b/sloth/src/parser/graph.rs
@@ -93,7 +93,9 @@ impl GraphBuilder {
writeln!(
&mut self.graph,
"N{} [shape=box label=\"DefineVariable\\n\\nIdentifier={}\\lType={}\\l\"];",
- stmt.id, identifier, typ
+ stmt.id,
+ identifier,
+ typ.clone().unwrap()
)?;
self.traverse_expr0(value)?;
}
diff --git a/sloth/src/parser/stmt.rs b/sloth/src/parser/stmt.rs
index 8bfbda5..75ef1b2 100644
--- a/sloth/src/parser/stmt.rs
+++ b/sloth/src/parser/stmt.rs
@@ -4,6 +4,9 @@ use crate::lexer::TokenType;
impl<'a> AstParser<'a> {
pub(super) fn statement(&mut self) -> Result<Stmt, ParsingError> {
+ // Checking what the next token is in order to figure out how we proceed. If
+ // it's not one of these tokens we assume it's an expression statement
+ // and parse the expression statement.
match self.peek().tt {
TokenType::OpeningBrace => self.block(),
@@ -25,6 +28,10 @@ impl<'a> AstParser<'a> {
// Consume the foreign token
self.consume(TokenType::Foreign, "Expected foreign")?;
+ // Foreign allows for you to interact with languages other than Sloth. When
+ // Sloth sees a foreign keyword it expects something to follow
+ // determining what from the other language you want to get, this is
+ // similar to the "statement" function but more trimmed down.
match &self.peek().tt {
TokenType::Fn => self.define_function(true),
@@ -50,6 +57,7 @@ impl<'a> AstParser<'a> {
}
}
+ // Build the actual if statement kind
let kind = StmtKind::IfStmt {
condition,
if_then: if_then.into(),
@@ -115,8 +123,11 @@ impl<'a> AstParser<'a> {
// Get the identifier and type
let identifier = self.consume_identifier()?;
- self.consume(TokenType::Colon, "Expected ':'")?;
- let typ = self.consume_type()?;
+ let typ = if self.consume(TokenType::Colon, "Expected ':'").is_ok() {
+ self.consume_type().ok()
+ } else {
+ None
+ };
// Get the default value
self.consume(TokenType::Eq, "Expected '='")?;
@@ -333,10 +344,10 @@ mod tests {
ExprKind::Literal(Literal::Integer(3)),
)),
}),
- typ: TypeIdentifier {
+ typ: Some(TypeIdentifier {
name: "Int".to_string(),
is_list: false,
- },
+ }),
}));
let mut parser = AstParser::new(tokens, SymbolTable::new());
@@ -393,10 +404,10 @@ mod tests {
Literal::Integer(1).into(),
)),
}),
- typ: TypeIdentifier {
+ typ: Some(TypeIdentifier {
name: "Int".to_owned(),
is_list: false,
- },
+ }),
}),
Stmt::without_table(7, StmtKind::AssignVariable {
identifier: "baz".to_owned(),