From a3c5134ee7581168947df8a050c332d7cb7aa426 Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 26 Jun 2023 23:41:21 -0500 Subject: [PATCH] Strings and so much more --- build.sh | 6 ++-- examples/hello.sloth | 40 ++------------------- examples/mandelbrot.sloth | 25 +++++++------ flake.lock | 66 ++++++++++++++++++++++++++-------- flake.nix | 2 +- sloth/src/analysis/setup.rs | 31 ++++++++++++---- sloth/src/codegen/mod.rs | 68 ++++++++++++++++++++++++++++++------ sloth/src/main.rs | 1 + sloth/src/symtable.rs | 1 + std/stdlib.sloth | 4 +-- stdlib.io | Bin 0 -> 2696 bytes test.c | 60 +++++++------------------------ 12 files changed, 172 insertions(+), 132 deletions(-) create mode 100644 stdlib.io 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, output: Box, 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 0000000000000000000000000000000000000000..4a91fad0231b0ac3e024f5c1e031d7b31b365659 GIT binary patch literal 2696 zcmb`I&1)N15WwHcYirvm(mEB?w1N2GOAi%J@u8)qeJx3~q$U-CKp-ZKtgPxZvb{)K zqlQ3T6o?cNP)H9=P9djIddMG8utDL4UWy7iaRiGaJ{GCRREVyZ+ESZRc#zr84(lML!hwsL_On6%OE0L6dJ9)O z+fFYD8}UNWFMFN8oS^nc-yQS{dU_hiXi)pT?{;Av)(7PGirr!1z##$aQT=CyX*XTL zTEFuI>W`ikeD`Y7!8lI!Fa#^8;n<&cafP(L-2Bs#-Gyn|#CU(Y|DE5U{mZV;?Z4Fj zW!FpkrTUwXoNm#>{dE4G>0Oxfd+}UxYY!aR6Fjz{cTbfkg(|xzRe54rl`{ub*=ein zk`DJ_f;P6YkPOpv=`2U6?1!9HWFt+GkRXC2zjJpcIqtOI%GMiZ6LPOmG8ZVh=cJOa zFDv=lK_$JmlG!CCr;aE&`JR%{q=Y6VG%2A;ku-T?h&w6b0OFiKCY-kKyq(K>19(tA zu>CqB!~|(%^JMQc7+kX!lbs-zCyjF(WaBZSAlpO(g!@4DqbC1lw~1jK1@*7m5@IiD zWFxZQG}vRZrw#U;Y_pdf{ULGB*wZYrA29z=el~L<@6CYuKJi85pXU9{k-UfIZh~`M z@z2hy;u9kC5}pIH&)|FqUl8YW;4?o=e4Z*X|AcsjIPdKP;-`u8Ih-LL5$Ah3MSNg! zyl3q54soCKG2+|g^Br9yJ|fQdbcOg+;(S+^i2HQj+$Y`#uFLns`@(%ApQn7xLpcvW z?o9(4a=Y-ifMcC)s-y22*k|OsU}KLjb`q%?9D88?%`UucaI?-OgPV2mZxRL9HTiXe zn{{p*+|0jca5I03o}gWS78eDX>C0YOXZ`--)+U!+Bvb&3gfe4<7+)e>k-(|x2+XW z5UA?_j1a&P0(Dv`T=}ZrtgeP)wc2Q`*L3=_PKOcFafI|`QEJ7_xQhC_Rn-5F+<-Ft zO*1P#!2g&aKPPHD(y@*GDX@^CHbs(?!-F@(H*7R9>ouZzKO4t}rdKcWL!q50T9Zi(k}|F?kIYXcHD O=~5ojd{l_+`Tqh#DQngM literal 0 HcmV?d00001 diff --git a/test.c b/test.c index cac1aef..f19dee9 100644 --- a/test.c +++ b/test.c @@ -1,53 +1,19 @@ #include -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); }