aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh6
-rw-r--r--examples/hello.sloth40
-rw-r--r--examples/mandelbrot.sloth25
-rw-r--r--flake.lock66
-rw-r--r--flake.nix2
-rw-r--r--sloth/src/analysis/setup.rs31
-rw-r--r--sloth/src/codegen/mod.rs68
-rw-r--r--sloth/src/main.rs1
-rw-r--r--sloth/src/symtable.rs1
-rw-r--r--std/stdlib.sloth4
-rw-r--r--stdlib.iobin0 -> 2696 bytes
-rw-r--r--test.c60
12 files changed, 172 insertions, 132 deletions
diff --git a/build.sh b/build.sh
index 1969d00..d4d648d 100755
--- a/build.sh
+++ b/build.sh
@@ -1,11 +1,11 @@
# Build Sloth
-cargo build --features=llvm-sys/prefer-dynamic
+cargo build
# Compile standard library
./target/debug/sloth std/stdio.sloth
mv output.o stdio.o
./target/debug/sloth std/stdlib.sloth
-mv output.o stdlib.io
+mv output.o stdlib.o
./target/debug/sloth std/stdmath.sloth
mv output.o stdmath.o
@@ -14,4 +14,4 @@ mv output.o stdmath.o
mv output.o main.o
# Generate binary
-gcc stdio.o std/stdio.c stdlib.o std/stdlib.c stdmath.o std/stdmath.c main.o -o program
+clang stdio.o std/stdio.c stdlib.o std/stdlib.c stdmath.o std/stdmath.c main.o -o program
diff --git a/examples/hello.sloth b/examples/hello.sloth
index db71b01..13415a9 100644
--- a/examples/hello.sloth
+++ b/examples/hello.sloth
@@ -1,40 +1,6 @@
-fn test() [Int] {
- var list: [Int] = [500, 5, 7];
+foreign fn print(x: String) Void;
- vpushi(list, 3);
- vpushi(list, 3);
- vpushi(list, 3);
- vpushi(list, 5);
-
- var x: Int = vpopi(list);
- vpushi(list, x);
- vpushi(list, x * 2);
- vpushi(list, x * 3);
-
- return list;
-}
-
-fn testtwo(list: [Int]) Int {
- #vpopi(list);
- var x: Int = vpopi(list);
- return x;
-}
-
-fn testthree(list: [Int]) Int {
- var x: Int = vlen(list);
- return x;
-}
-
-foreign fn testback(x: Int) Void;
-
-fn testfour(list: [Int]) Int {
- vseti(list, 0, 888);
- var i: Int = 0;
- while i < vlen(list) {
- var value: Int = vgeti(list, i);
- testback(value);
- i = i + 1;
- }
+fn main() Int {
+ print("gaming\n");
return 0;
}
-
diff --git a/examples/mandelbrot.sloth b/examples/mandelbrot.sloth
index f9ebdc8..1765e8e 100644
--- a/examples/mandelbrot.sloth
+++ b/examples/mandelbrot.sloth
@@ -1,34 +1,37 @@
-foreign fn termpos(x: Int, y: Int);
foreign fn print(str: String);
+foreign fn printint(i: Int);
+foreign fn as_int(x: Float) Int;
+
+foreign fn termpos(x: Int, y: Int) Void;
fn main() Int{
var size: Float = 200.0;
var maxVal: Float = 4.0;
- var maxIter: Int = 50;
+ var maxIter: Float = 50.0;
var plane: Float = 4.0;
# lmao
- var x: Int = 0;
+ var x: Float = 0.0;
while x < size {
- var y: Int = 0;
+ var y: Float = 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: Int = 0;
- while (zReal * zReal + zImg * zImg) <= maxVal && count < 4{
+ var count: Float = 0.0;
+ while (zReal * zReal + zImg * zImg) <= maxVal && count < maxIter {
var temp: Float = (zReal * zReal) - (zImg * zImg) + cReal;
zImg = 2.0 * zReal * zImg + cImg;
zReal = temp;
- count = count + 1;
+ count = count + 1.0;
}
- if count == maxIter {
- termpos(x, y);
+ if as_int(count) == as_int(maxIter) {
+ termpos(as_int(x), as_int(y));
print("*");
}
- y = y + 1;
+ y = y + 1.0;
}
- x = x + 1;
+ x = x + 1.0;
}
return 0;
}
diff --git a/flake.lock b/flake.lock
index 13cfc0a..771cadc 100644
--- a/flake.lock
+++ b/flake.lock
@@ -17,12 +17,15 @@
}
},
"flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
"locked": {
- "lastModified": 1678901627,
- "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
+ "lastModified": 1687709756,
+ "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
+ "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7",
"type": "github"
},
"original": {
@@ -32,12 +35,15 @@
}
},
"flake-utils_2": {
+ "inputs": {
+ "systems": "systems_2"
+ },
"locked": {
- "lastModified": 1659877975,
- "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
+ "lastModified": 1681202837,
+ "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
+ "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
@@ -48,11 +54,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1679872478,
- "narHash": "sha256-ghGb29FgfQ1FHGSug/mF37a7i0C82Q0Cw0VfySX03MM=",
+ "lastModified": 1687832285,
+ "narHash": "sha256-NPYGZJl5ppAVXaqZtiL8ha4bISfNY7QZHaeBBBYGPOI=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "8170949e3a2ca93be040516bd66e642c08dbab06",
+ "rev": "005c84e12a79f8f81e66e46ad8e081afef8ac411",
"type": "github"
},
"original": {
@@ -64,11 +70,11 @@
},
"nixpkgs_2": {
"locked": {
- "lastModified": 1665296151,
- "narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=",
+ "lastModified": 1681358109,
+ "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "14ccaaedd95a488dd7ae142757884d8e125b3363",
+ "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
"type": "github"
},
"original": {
@@ -92,11 +98,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
- "lastModified": 1679797409,
- "narHash": "sha256-5vpDBK/bNHXO+/lw1XUjroJzbusujZPGwp6nLgmy55Y=",
+ "lastModified": 1687746941,
+ "narHash": "sha256-wsSRCmPQ1+uXsDNnEH2mN4ZVtHHpfavA4FrQnCb5A44=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "7f38143d19432a0f9780197febe3fac9d3b0773a",
+ "rev": "b91d162355e88de89b379f3d6a459ade92704474",
"type": "github"
},
"original": {
@@ -104,6 +110,36 @@
"repo": "rust-overlay",
"type": "github"
}
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_2": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
}
},
"root": "root",
diff --git a/flake.nix b/flake.nix
index 64485bd..5c82957 100644
--- a/flake.nix
+++ b/flake.nix
@@ -20,7 +20,7 @@
};
rustStable = pkgs.rust-bin.stable.latest.default;
- rustNightly = pkgs.rust-bin.nightly."2023-02-10".default;
+ rustNightly = pkgs.rust-bin.nightly."2023-06-19".default;
rustPlatform = pkgs.makeRustPlatform {
cargo = rustStable;
diff --git a/sloth/src/analysis/setup.rs b/sloth/src/analysis/setup.rs
index c405977..16ac100 100644
--- a/sloth/src/analysis/setup.rs
+++ b/sloth/src/analysis/setup.rs
@@ -1,7 +1,7 @@
use super::AnalysisError;
use crate::parser::ast::{
- AstNode, Expr, ExprKind, Function, FunctionInput, FunctionKind, Literal, Stmt, StmtKind,
- TypeIdentifier,
+ AstNode, BinaryOp, Expr, ExprKind, Function, FunctionInput, FunctionKind, Literal, Stmt,
+ StmtKind, TypeIdentifier,
};
use crate::symtable::{Symbol, SymbolTable, Type, ValueSymbol};
@@ -181,6 +181,7 @@ pub(super) fn propagate_types(node: &mut Expr) -> Result<(), AnalysisError> {
last.expect("need 1 element in literal im sozzy")
}
+ Literal::String(_) => Type::String,
_ => todo!(),
},
ExprKind::Identifier(identifier) => {
@@ -189,7 +190,7 @@ pub(super) fn propagate_types(node: &mut Expr) -> Result<(), AnalysisError> {
AnalysisError::UnknownIdentifier(node.line, identifier.to_owned()),
)?
}
- ExprKind::BinaryOp { lhs, rhs, .. } => {
+ ExprKind::BinaryOp { lhs, rhs, op } => {
// Propagating the types to the children
propagate_types(lhs)?;
propagate_types(rhs)?;
@@ -198,9 +199,27 @@ pub(super) fn propagate_types(node: &mut Expr) -> Result<(), AnalysisError> {
return Err(AnalysisError::TypeMismatch(node.line));
}
- lhs.typ
- .clone()
- .ok_or(AnalysisError::Unknown(node.line, "owo?? choco???"))?
+ match op {
+ BinaryOp::Add
+ | BinaryOp::Con
+ | BinaryOp::Sub
+ | BinaryOp::Mul
+ | BinaryOp::Div
+ | BinaryOp::Mod => lhs
+ .typ
+ .clone()
+ .ok_or(AnalysisError::Unknown(node.line, "owo?? choco???"))?,
+ BinaryOp::Lt
+ | BinaryOp::Gt
+ | BinaryOp::LtEq
+ | BinaryOp::GtEq
+ | BinaryOp::EqEq
+ | BinaryOp::NotEq => Type::Boolean,
+ BinaryOp::LogicalAnd | BinaryOp::LogicalOr | BinaryOp::Range => lhs
+ .typ
+ .clone()
+ .ok_or(AnalysisError::Unknown(node.line, "owo?? choco???"))?,
+ }
}
ExprKind::UnaryOp { value, .. } => {
propagate_types(value)?;
diff --git a/sloth/src/codegen/mod.rs b/sloth/src/codegen/mod.rs
index dacc3a5..3120d11 100644
--- a/sloth/src/codegen/mod.rs
+++ b/sloth/src/codegen/mod.rs
@@ -174,15 +174,7 @@ impl<'ctx> Codegen<'ctx> {
}
StmtKind::DefineFunction(function) => {
let table = code.symtable.clone();
- self.codegen_function(
- table,
- // if let FunctionKind::Normal { body } = &function.kind {
- // Some(body.symtable.clone())
- // } else {
- // None
- // },
- function.clone(),
- );
+ self.codegen_function(table, function.clone());
// If the function is written in sloth (as opposed to an extern one) we generate
// the block contents
@@ -262,6 +254,14 @@ impl<'ctx> Codegen<'ctx> {
ptr_to_that.fn_type(&inputs_typ, false)
}
+ Type::String => {
+ let i8_type = self.context.i8_type().as_basic_type_enum();
+ let ptr_type = i8_type
+ .ptr_type(AddressSpace::default())
+ .as_basic_type_enum();
+
+ ptr_type.fn_type(&inputs_typ, false)
+ }
_ => todo!(),
};
@@ -314,7 +314,11 @@ impl<'ctx> Codegen<'ctx> {
BinaryOp::EqEq => self.builder.build_int_compare(EQ, l, r, ""),
BinaryOp::NotEq => self.builder.build_int_compare(NE, l, r, ""),
- _ => panic!(),
+
+ BinaryOp::LogicalAnd => self.builder.build_and(l, r, "logand"),
+ BinaryOp::LogicalOr => self.builder.build_or(l, r, "logor"),
+
+ _ => panic!("{op:?}"),
}
.into()
}
@@ -481,6 +485,44 @@ impl<'ctx> Codegen<'ctx> {
vector_ptr.as_basic_value_enum()
}
+ Literal::String(value) => {
+ let i32_type = self.context.i32_type();
+ let i8_type = self.context.i8_type();
+ // let ptr_type = i8_type
+ // .ptr_type(AddressSpace::default())
+ // .as_basic_type_enum();
+ //
+ // ptr_type.fn_type(&inputs_typ, false)
+
+ let mut values = value
+ .as_bytes()
+ .iter()
+ .map(|it| i8_type.const_int(*it as u64, false))
+ .collect_vec();
+ values.push(i8_type.const_int(b'\0' as u64, false));
+
+ let const_arr = i8_type.const_array(&values);
+
+ let ptr = self
+ .builder
+ .build_array_malloc(
+ i8_type,
+ i32_type.const_int(values.len() as u64 + 5, false),
+ "str",
+ )
+ .unwrap();
+
+ // self.builder.build_memcpy(
+ // ptr,
+ // 0,
+ // const_arr,
+ // 0,
+ // i32_type.const_int(values.len() as u64, false),
+ // );
+ self.builder.build_store(ptr, const_arr);
+
+ ptr.as_basic_value_enum()
+ }
_ => unimplemented!(),
}
}
@@ -506,6 +548,12 @@ impl<'ctx> Codegen<'ctx> {
ptr_to_that.as_basic_type_enum()
}
// Type::Array { typ, len } => self.type_as_basic_type(*typ).array_type(len).into(),
+ Type::String => {
+ let i8_type = self.context.i8_type().as_basic_type_enum();
+ i8_type
+ .ptr_type(AddressSpace::default())
+ .as_basic_type_enum()
+ }
_ => todo!(),
}
}
diff --git a/sloth/src/main.rs b/sloth/src/main.rs
index ff3df31..3112e28 100644
--- a/sloth/src/main.rs
+++ b/sloth/src/main.rs
@@ -48,6 +48,7 @@ fn main() {
global_symtable.insert("Int".into(), Symbol::Type(Type::Integer));
global_symtable.insert("Float".into(), Symbol::Type(Type::Float));
global_symtable.insert("Bool".into(), Symbol::Type(Type::Boolean));
+ global_symtable.insert("String".into(), Symbol::Type(Type::String));
// Inputs aren't type checked but outputs are
let dummyi = Symbol::Value(ValueSymbol {
diff --git a/sloth/src/symtable.rs b/sloth/src/symtable.rs
index 8af1c60..eb3509a 100644
--- a/sloth/src/symtable.rs
+++ b/sloth/src/symtable.rs
@@ -151,6 +151,7 @@ pub enum Type {
Integer,
Float,
Boolean,
+ String,
Function {
inputs: Vec<Type>,
output: Box<Type>,
diff --git a/std/stdlib.sloth b/std/stdlib.sloth
index d7ddeff..cc404f6 100644
--- a/std/stdlib.sloth
+++ b/std/stdlib.sloth
@@ -1,10 +1,10 @@
foreign fn wait(x: Int) Void;
foreign fn print(str: String) Void;
foreign fn slen(str: String) Int;
-foreign fn charAt(str: String) Char;
+# foreign fn charAt(str: String) Char;
foreign fn parse_int(str: String) Int;
-fn termpos(x: int, y: int) Void {
+fn termpos(x: Int, y: Int) Void {
print("\x1b[");
print(x);
print(";");
diff --git a/stdlib.io b/stdlib.io
new file mode 100644
index 0000000..4a91fad
--- /dev/null
+++ b/stdlib.io
Binary files differ
diff --git a/test.c b/test.c
index cac1aef..f19dee9 100644
--- a/test.c
+++ b/test.c
@@ -1,53 +1,19 @@
#include <stdio.h>
-typedef struct {
- int size;
- int cap;
- int* inner;
-} IntVec;
-
-IntVec* test();
-int testtwo(IntVec*);
-int testthree(IntVec*);
-int testfour(IntVec*);
-
-void testback(int x) {
- printf("%d, ", x);
+void print(char* x) {
+ printf("%s", x);
+}
+void printfl(float x) {
+ printf("%f", x);
+}
+void printint(int x) {
+ printf("%d", x);
}
-int main() {
- IntVec* v = test();
-
- int size = (*v).size;
- int cap = (*v).cap;
- int* inner = (*v).inner;
-
- printf("%d\n", size);
- printf("%d\n", cap);
-
- for (int i = 0; i < size; ++i) {
- int value = inner[i];
- printf("%d ", value);
- }
- puts("\n\n");
-
- testtwo(v);
-
- size = (*v).size;
- cap = (*v).cap;
- inner = (*v).inner;
-
- printf("%d\n", size);
- printf("%d\n", cap);
+int as_int(float x) {
+ return (int) x;
+}
- for (int i = 0; i < size; ++i) {
- int value = inner[i];
- printf("%d ", value);
- }
- puts("\n\n");
- int i = testthree(v);
- printf("%d ", i);
- puts("\n\n");
- testfour(v);
- puts("");
+void termpos(int x, int y) {
+ printf("\x1b[%d;%dH", x, y);
}