diff --git a/Cargo.toml b/Cargo.toml index bcd512f..5fb3970 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" [dependencies] laddertypes = { path = "../lib-laddertypes" } tisc = { path = "../lib-tisc" } +iterate-text = "0.0.1" diff --git a/main.lt b/main.lt new file mode 100644 index 0000000..eb654f0 --- /dev/null +++ b/main.lt @@ -0,0 +1,196 @@ +{ + /* + * Integer Operations + */ + let int-sign = λx:ℤ~machine.Int64 ↦ bit-and (bit-shr x 63) 1; + let int-neg = λx:ℤ~machine.Int64 ↦ i+ (bit-neg x) 1; + let int-abs = λx:ℤ~machine.Int64 ↦ if( int-sign x ) { int-neg x; } else { x; }; + let int-lt = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ int-sign (i- a b); + let int-gt = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ int-sign (i- b a); + let int-eq = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ if (i- a b) { 0; } else { 1; }; + let int-lte = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ bit-or (int-lt a b) (int-eq a b); + let int-gte = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ bit-or (int-gt a b) (int-eq a b); + let int-min = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ if( int-lt a b ) { a; } else { b; }; + let int-max = λ{ a:ℤ~machine.Int64; b:ℤ~machine.Int64; } ↦ if( int-gt a b ) { a; } else { b; }; + + /* Euclidean Algorithm to calculate greatest common divisor + */ + let gcd = λ{ + a : ℤ ~ machine.Int64; + b : ℤ ~ machine.Int64; + } ↦ { + while( b ) { + let tmp = i% a b; + ! a b; + ! b tmp; + } + a; + }; + + /* least common multiple + */ + let lcm = λ{ + a : ℤ ~ machine.Int64; + b : ℤ ~ machine.Int64; + } ↦ i* (int-abs a) (i/ (int-abs b) (gcd a b)); + + + /* Implementation of Rational Numbers + */ + let ratio-scale = λ{ + {p:ℕ; q:ℕ;} : ℚ ~ ; + n : ℕ ~ machine.UInt64 ; + } ↦ { + i* q n; + i* p n; + }; + + let ratio-normalize = λ{ + p: ℤ~machine.Int64; + q: ℤ~machine.Int64; + } : ℚ ~ + ↦ { + let s = gcd p q; + i/ q s; + i/ p s; + }; + + let ratio-add = λ{ + {ap:ℕ; aq:ℕ;}: ℚ ~ ; + {bp:ℕ; bq:ℕ;}: ℚ ~ ; + } ↦ { + let l = lcm aq bq; + let as = i/ l aq; + let bs = i/ l bq; + + i* aq as; + i+ (i* ap as) (i* bp bs); + }; + + let ratio-mul = λ{ + {ap:ℤ; aq:ℤ;}: ℚ ~ ; + {bp:ℤ; bq:ℤ;}: ℚ ~ ; + } ↦ ratio-normalize (i* ap bp) (i* aq bq); + + let morph-int-to-float = + λx: ℤ ~ machine.Int64 ~ machine.Word + ↦ { + /* todo */ + 0; + }; + + let morph-ratio-to-float = + λ{ + p : ℤ~machine.Int64; + q : ℤ~machine.Int64; + } : ℚ~ + ↦ f/ (morph-int-to-float p) (morph-int-to-float q); + + + + /* string output + */ + let print-nullterm = + λ{} : < Seq Char ~Ascii ~ machine.Word > + ~ < NullTerminatedArray machine.Word > + ↦ { + while(dup) { emit; } + drop; + }; + + print-nullterm 'H' 'a' 'l' 'l' 'o' ' ' 'W' 'e' 'l' 't' '!' '\n' '\0'; + + /* integer formatting + */ + let fmt-uint-radix = λ{ + radix : ℕ ~ ℤ_2^64 ~ machine.UInt64; + x : ℕ ~ ℤ_2^64 ~ machine.UInt64; + } ↦ { + if( x ) { + while( x ) { + let digit = (i% x radix); + + if( int-lt digit 10 ) { + i+ '0' digit; + } else { + i+ (i- 'a' 10) digit; + }; + ! x (i/ x radix); + } + } else { + '0'; + }; + }; + + let fmt-int-radix = λ{ + radix: ℕ ~ ℤ_2^64 ~ machine.UInt64; + x : ℤ ~ machine.Int64; + } ↦ { + fmt-uint-radix radix (int-abs x); + if( int-sign x ) { '-'; }; + }; + + let fmt-uint = λx:ℕ ↦ fmt-uint-radix 10 x; + let fmt-int = λx:ℤ ↦ fmt-int-radix 10 x; + + /* ratio formatting + */ + let fmt-ratio = λ{ p:ℤ; q:ℤ; } : ℚ~ ↦ { + fmt-int q;':';fmt-int p; + }; + + + + + /* test ratio + */ + print-nullterm + (fmt-ratio { 4; int-neg 3; }) + ' ''*'' ' + (fmt-ratio { 7; 4; }) + ' ''='' ' + (fmt-ratio (ratio-mul { 4; int-neg 3; } { 7; 4; })) + '\n''\0'; + + + /* Vec3i + */ + let vec3i-add = λ{ + { ax:ℤ_2^64; ay:ℤ_2^64; az:ℤ_2^64; } : ; + { bx:ℤ_2^64; by:ℤ_2^64; bz:ℤ_2^64; } : ; + } ↦ { + i+ az bz; + i+ ay by; + i+ ax bx; + }; + + let fmt-vec3i = + λ{ x:ℤ_2^64; y:ℤ_2^64; z:ℤ_2^64; } : + ↦ { + '}'; + fmt-int z; '='; 'z'; ' '; ';'; + fmt-int y; '='; 'y'; ' '; ';'; + fmt-int x; '='; 'x'; '{'; + }; + + + + /* Colors + */ + let red-u8rgb + : Color ~ RGB ~ > + = λ{} ↦ { 0; 0; 255; }; + + let green-u8rgb = λ{} ↦ { 0; 255; 0; }; + let blue-u8rgb = λ{} ↦ { 255; 0; 0; }; + let yellow-u8rgb = λ{} ↦ { 0; 220; 220; }; + + print-nullterm + (fmt-vec3i green-u8rgb) + ' ''+'' ' + (fmt-vec3i blue-u8rgb) + ' ''='' ' + (fmt-vec3i (vec3i-add green-u8rgb blue-u8rgb)) + '\n''\0'; +} + diff --git a/src/main.rs b/src/main.rs index 0082d2d..2f10e05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,13 +20,13 @@ use crate::{ fn compile( scope: &Arc>, name: &str, - source: &str, + source: impl Iterator, ) -> Vec { ProcedureCompiler::new(scope) .compile( &parser::parse_expr( &scope.read().unwrap().typectx, - &mut lexer::LTIRLexer::from(source.chars().peekable()) + &mut lexer::LTIRLexer::from(source.peekable()) .filter(|tok| match tok { (_, Ok(lexer::LTIRToken::Comment(_))) => false, _ => true @@ -40,10 +40,10 @@ fn compile( /* TODO: - * - write to address resulting from expression - * - `::` -> '.' and allow ↦ only * - Parser error reporting * - Compiler error reporting + * - write to address resulting from expression + * - sized objects * - Typecheck for LTExpr::Application * - typecheck & inference for rest */ @@ -57,100 +57,16 @@ fn main() { let main_scope = Scope::with_parent(&root_scope); let typectx = main_scope.read().unwrap().typectx.clone(); + let args: Vec = std::env::args().collect(); + let path = &args[1]; + let iter_chars = iterate_text::file::characters::IterateFileCharacters::new(path); + /* link assembly-program to symbols */ - linker.add_procedure( - "main", - compile( - &main_scope, - "main", - "{ - let print-nullterm = - λ{} : < Seq Char ~Ascii ~ machine.Word > - ~ < NullTerminatedArray machine.Word > - ↦ { - while(dup) { emit; } - drop; - }; - - print-nullterm 'H' 'a' 'l' 'l' 'o' ' ' 'W' 'e' 'l' 't' '!' '\n' '\0'; - - let fmt-uint = - λx : ℕ ~ ℤ_2^64 ~ machine.UInt64 - ↦ { - if( x ) { - while( x ) { - i+ '0' (i% x 10); - ! x (i/ x 10); - } - } else { - '0'; - }; - }; - - let print-uint = λx:ℕ ↦ print-nullterm (fmt-uint x) '\0'; - - let int-neg = λx : ℤ ~ machine.Int64 ~ machine.Word ↦ i+ (bit-neg x) 1; - let int-sign = λx : ℤ ~ machine.Int64 ~ machine.Word ↦ bit-and (bit-shr x 63) 1; - - let int-lt = λ{ - a : ℤ ~ machine.Int64; - b : ℤ ~ machine.Int64; - } ↦ int-sign (i- a b); - - let int-gt = λ{ - a : ℤ ~ machine.Int64; - b : ℤ ~ machine.Int64; - } ↦ int-sign (i- b a); - - let int-eq = λ{ - a : ℤ ~ machine.Int64; - b : ℤ ~ machine.Int64; - } ↦ if (i- a b) { 0; } else { 1; }; - - let int-lte = λa:ℤ ↦ λb:ℤ ↦ bit-or (int-lt a b) (int-eq a b); - let int-gte = λa:ℤ ↦ λb:ℤ ↦ bit-or (int-gt a b) (int-eq a b); - - let int-min = λ{ - a : ℤ ~ machine.Int64; - b : ℤ ~ machine.Int64; - } ↦ if( int-lt a b ) { a; } else { b; }; - - let int-max = λ{ - a : ℤ ~ machine.Int64; - b : ℤ ~ machine.Int64; - } ↦ if( int-gt a b ) { a; } else { b; }; - - let vec3i-add = λ{ - { ax:ℤ_2^64; ay:ℤ_2^64; az:ℤ_2^64; } : ; - { bx:ℤ_2^64; by:ℤ_2^64; bz:ℤ_2^64; } : ; - } ↦ { - i+ az bz; - i+ ay by; - i+ ax bx; - }; - - let fmt-vec3i = - λ{ x:ℤ_2^64; y:ℤ_2^64; z:ℤ_2^64; } : - ↦ { - '}'; - fmt-uint z; '='; 'z'; ' '; ';'; - fmt-uint y; '='; 'y'; ' '; ';'; - fmt-uint x; '='; 'x'; '{'; - }; - - let red-u8rgb - : Color ~ RGB ~ > - = λ{} ↦ { 0; 0; 255; }; - let green-u8rgb = λ{} ↦ { 0; 255; 0; }; - let blue-u8rgb = λ{} ↦ { 255; 0; 0; }; - let yellow-u8rgb = λ{} ↦ { 0; 220; 220; }; - - print-nullterm (fmt-vec3i (vec3i-add green-u8rgb blue-u8rgb)) '\n' '\0'; - }" - ), - ); + linker.add_procedure("main", compile(&main_scope, "main", iter_chars)); + /* load & run compiled bytecode + */ let main_addr = linker .get_link_addr(&"main".into()) .expect("'main' not linked");