// -*- mode: java; -*- // top-level default import struct sys { // libc bindings /** https://www.man7.org/linux/man-pages/man2/.2.html */ struct libc { i32 errno = "C"; // fd buf len -> len { i32 i64 u32 -> u32 } write = "C"; // fd buf len -> len { i32 i64 u32 -> u32 } read = "C"; // status { i32 -> i32 } _exit = "C"; // addr len prot flags fd off -> void* { i64 i64 i32 i32 i32 i32 -> i64 } mmap = "C"; // mmap flags i32 PROT_EXEC = 4; i32 PROT_READ = 1; i32 PROT_WRITE= 2; i32 PROT_NONE = 0; i32 MAP_PRIVATE = 2; i32 MAP_ANON = 32; }; struct ary { val copy = { u8[] dst, int doff, u8[~] src, int soff, int len -> for( int i=0; i if( len+len2 < buf# ) return self; int newlen = buf# * 2; while( len+len2 >= newlen ) newlen *= 2; u8[] buf2 = new u8[newlen]; sys.ary.copy(buf2,0,buf,0,buf#); buf = buf2; self; }; // Add a character to aryu8 val add = { u8 c -> _grow(1).buf[len++] = c; self; }; // Add a plain array to the aryu8 val addAry = { u8[~] ary -> _grow(ary#); sys.ary.copy(buf,len,ary,0,ary#); len += ary#; self; }; // Remove x chars from the tail. val undo = { int x -> len = len >= x ? len-x : 0; self; }; // Print ASCII number into aryu8 val num = { i64 x -> if( !x ) { add('0'); return self; } if( x < 0 ) { add('-'); x = -x; } i64 ten = 1, log = 0; while( ten <= x ) { ten *= 10; log++; } for( int i=0; i i64 ptr = buf; sys.libc.write(fd,ptr,len); }; }; // Scanner; a simple string parser. struct Scan { int !x; u8[~] buf; // Skip whitespace val skip = { -> while( buf[x] <= ' ' ) x++; return self; }; // True if find required character, and skip it; else False. val match = { u8 c -> skip(); if( buf[x] != c ) return false; x++; return true; }; // Parse a simple number val number = { -> skip(); bool neg = match('-'); i64 n = 0; while( '0' <= buf[x] & buf[x] <= '9' ) n = n*10 + (buf[x++] - '0'); return neg ? -n : n; }; }; // Ary/Vector of i64s struct aryi64 { u32 !len = 0; i64[] !buf; // Grow as needed val _grow = { int len2 -> if( len+len2 < buf# ) return self; int newlen = buf# * 2; while( len+len2 >= newlen ) newlen *= 2; i64[] buf2 = new i64[newlen]; for( int i=0; i _grow(1).buf[len++] = c; self; }; // Write to aryu8 val str = { -> // TODO: clunky default constructor syntax var str = new sys.aryu8 { buf = new u8[1]; }.add('['); for( int i=0; i sys.Scan !s = new sys.Scan{ buf = str; }; if( !s.match('[') ) return null; // Array of parsed results var nums = new sys.aryi64{ buf=new i64[1]; }; // Parse a list of numbers if( !s.match(']') ) { // Handle the empty list // Parse "123, " until a something else while( s.x < s.buf# ) { nums.add(s.number()); if( !s.match(',') ) break; }; if( !s.match(']') ) return null; // Close the list } return nums; }; struct io { // Print string to stdout val p = { u8[~] str -> i64 ptr = str; // cast array base to i64 return sys.libc.write(1,ptr,str#); }; // Return stdin as a u8[] val stdin = { -> var buf = new u8[8*1024]; i64 ptr = buf; int len = 0; while( true ) { int rez = sys.libc.read(0,ptr,buf#); if( rez < 0 ) sys.libc._exit(sys.libc.errno); len += rez; if( rez < buf# ) break; sys.libc._exit(-2); // Need to implement } // Compress var dst = new u8[len]; return sys.ary.copy(dst,0,buf,0,len); }; }; };