Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
202 changes: 101 additions & 101 deletions docs/SPECIFICATION.html

Large diffs are not rendered by default.

60 changes: 30 additions & 30 deletions lib/std/csprng.pre
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
! ChaCha20-based cryptographically secure pseudorandom number generator

INT: MASK32 = SUB( POW(0b10, 0b100000), 1 ) ! 2^32-1
INT MASK32 = SUB( POW(0b10, 0b100000), 1 ) ! 2^32-1

! ChaCha20 constants ("expand 32-byte k")
MAP: CH_CONST = < ^
MAP CH_CONST = < ^
0b0 = 0b01100001011100000111000001100101, ^
0b1 = 0b00110011001000000110010001101110, ^
0b10 = 0b01111001011000100010110100110010, ^
0b11 = 0b01101011001000000110010101110100 ^
>

TNS: ch_key = TNS([0b1000], 0b0) ! 8 words
TNS: ch_nonce = [0b0, 0b0, 0b0] ! use literals for short TNS
INT: ch_counter = 0
TNS: ch_buf = TNS([0b10000], 0b0) ! 16 words
INT: ch_buf_pos = TLEN(ch_buf, 0b1) ! set to buffer length to force refill
TNS ch_key = TNS([0b1000], 0b0) ! 8 words
TNS ch_nonce = [0b0, 0b0, 0b0] ! use literals for short TNS
INT ch_counter = 0
TNS ch_buf = TNS([0b10000], 0b0) ! 16 words
INT ch_buf_pos = TLEN(ch_buf, 0b1) ! set to buffer length to force refill

FUNC INT: ROTL32(INT: x, INT: n){
INT: x32 = BAND(x, MASK32)
INT: left = BAND(SHL(x32, n), MASK32)
INT: right = SHR(x32, SUB(0b100000, n)) ! 32 - n
FUNC INT ROTL32(INT x, INT n){
INT x32 = BAND(x, MASK32)
INT left = BAND(SHL(x32, n), MASK32)
INT right = SHR(x32, SUB(0b100000, n)) ! 32 - n
RETURN( BAND(BOR(left, right), MASK32) )
}

FUNC INT: QR(TNS: s, INT: ia, INT: ib, INT: ic, INT: id){
INT: a = s[ia]
INT: b = s[ib]
INT: c = s[ic]
INT: d = s[id]
FUNC INT QR(TNS s, INT ia, INT ib, INT ic, INT id){
INT a = s[ia]
INT b = s[ib]
INT c = s[ic]
INT d = s[id]

a = BAND( ADD(a, b), MASK32 )
d = ROTL32( BXOR(d, a), 0b10000 ) ! 16
Expand All @@ -45,10 +45,10 @@ FUNC INT: QR(TNS: s, INT: ia, INT: ib, INT: ic, INT: id){
RETURN(0)
}

FUNC INT: CHACHA_BLOCK(){
TNS: k = ch_key
TNS: n = ch_nonce
TNS: state = [ ^
FUNC INT CHACHA_BLOCK(){
TNS k = ch_key
TNS n = ch_nonce
TNS state = [ ^
CH_CONST<0b0>, ^
CH_CONST<0b1>, ^
CH_CONST<0b10>, ^
Expand Down Expand Up @@ -98,15 +98,15 @@ FUNC INT: CHACHA_BLOCK(){
RETURN(0b0)
}

FUNC INT: REFILL_BUF(){
FUNC INT REFILL_BUF(){
CHACHA_BLOCK()
ch_buf_pos = 0b0
ch_counter = BAND( ADD(ch_counter, 0b1), MASK32 )
RETURN(0b0)
}

FUNC INT: DERIVE_KEY_AND_NONCE(INT: seed){
INT: s = BAND(seed, MASK32)
FUNC INT DERIVE_KEY_AND_NONCE(INT seed){
INT s = BAND(seed, MASK32)
FOR(i, 0b1000){ ! 8 key words (1000 == 8)
s = BAND( ADD( MUL(s, ^
0b01000001110001100100111001101101), ^
Expand All @@ -126,33 +126,33 @@ FUNC INT: DERIVE_KEY_AND_NONCE(INT: seed){
RETURN(0b0)
}

FUNC INT: SEED(INT: seed){
FUNC INT SEED(INT seed){
DERIVE_KEY_AND_NONCE(seed)
ch_counter = 0b0
ch_buf = TNS([0b10000], 0b0)
ch_buf_pos = TLEN(ch_buf, 0b1) ! set to buffer length to force refill
RETURN(ch_counter)
}

FUNC INT: NEXT(){
FUNC INT NEXT(){
IF( GTE(ch_buf_pos, TLEN(ch_buf, 0b1)) ){ ! buffer length
REFILL_BUF()
}
INT: v = ch_buf[ ADD(ch_buf_pos, 0b1) ]
INT v = ch_buf[ ADD(ch_buf_pos, 0b1) ]
ch_buf_pos = ADD(ch_buf_pos, 0b1)
RETURN(v)
}

FUNC INT: RANGE(INT: max){
FUNC INT RANGE(INT max){
ASSERT( GT(max, 0b0) )
RETURN( MOD(NEXT(), max) )
}

FUNC INT: RANGE_MIN_MAX(INT: min, INT: max){
FUNC INT RANGE_MIN_MAX(INT min, INT max){
ASSERT( LTE(min, max) )
INT: range = SUB(max, min)
INT range = SUB(max, min)
IF( EQ(range, 0b0) ){ RETURN(min) }
ASSERT( GT(range, 0b0) )
INT: offset = RANGE(range)
INT offset = RANGE(range)
RETURN( ADD(offset, min) )
}
52 changes: 26 additions & 26 deletions lib/std/diff.pre
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
! diff utilities for Prefix

FUNC STR: _append_line(STR: acc, STR: line){
FUNC STR _append_line(STR acc, STR line){
IF( EQ(acc, "") ){ RETURN(line) } ELSE { RETURN( JOIN(acc, "\n", line) ) }
}

FUNC STR: UNIFIED(STR: mod, STR: src){
TNS: a = SPLIT(mod, "\n")
TNS: b = SPLIT(src, "\n")
INT: la = TLEN(a, 0d1)
INT: lb = TLEN(b, 0d1)
INT: n = MAX(la, lb)
STR: out = ""
INT: i = 0d1
FUNC STR UNIFIED(STR mod, STR src){
TNS a = SPLIT(mod, "\n")
TNS b = SPLIT(src, "\n")
INT la = TLEN(a, 0d1)
INT lb = TLEN(b, 0d1)
INT n = MAX(la, lb)
STR out = ""
INT i = 0d1
WHILE( LTE(i, n) ){
STR: left = ""
STR left = ""
IF( LTE(i, la) ){ left = a[i] }
STR: right = ""
STR right = ""
IF( LTE(i, lb) ){ right = b[i] }

IF( EQ(left, right) ){
IF( NEQ(left, "")){
STR: line = JOIN(" ", left)
STR line = JOIN(" ", left)
out = _append_line(out, line)
}
} ELSE {
Expand All @@ -36,30 +36,30 @@ FUNC STR: UNIFIED(STR: mod, STR: src){
RETURN(out)
}

FUNC STR: CONTEXT(STR: mod, STR: src){
FUNC STR CONTEXT(STR mod, STR src){
! For simplicity, use the same output as UNIFIED but with a ' ' prefix
STR: u = UNIFIED(mod, src)
STR u = UNIFIED(mod, src)
IF( EQ(u, "") ){ RETURN("") }
! Prepend a simple header to resemble context diff
RETURN( JOIN("*** a", "\n", u) )
}

FUNC STR: SIDE_BY_SIDE(STR: mod, STR: src){
TNS: a = SPLIT(mod, "\n")
TNS: b = SPLIT(src, "\n")
INT: la = TLEN(a, 0d1)
INT: lb = TLEN(b, 0d1)
INT: n = MAX(la, lb)
STR: out = ""
INT: i = 0d1
FUNC STR SIDE_BY_SIDE(STR mod, STR src){
TNS a = SPLIT(mod, "\n")
TNS b = SPLIT(src, "\n")
INT la = TLEN(a, 0d1)
INT lb = TLEN(b, 0d1)
INT n = MAX(la, lb)
STR out = ""
INT i = 0d1
WHILE( LTE(i, n) ){
STR: left = ""
STR left = ""
IF( LTE(i, la) ){ left = a[i] }
STR: right = ""
STR right = ""
IF( LTE(i, lb) ){ right = b[i] }
STR: marker = " "
STR marker = " "
IF( NEQ(left, right)){ marker = "|" }
STR: line = JOIN(left, " ", marker, " ", right)
STR line = JOIN(left, " ", marker, " ", right)
out = _append_line(out, line)
i = ADD(i, 0d1)
}
Expand Down
8 changes: 4 additions & 4 deletions lib/std/gui/init.pre
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

EXTEND(EXTENSION: gui)

FUNC INT: SCREEN_WIDTH(){
FUNC INT SCREEN_WIDTH(){
RETURN(SCREEN()[0d1])
}

FUNC INT: SCREEN_HEIGHT(){
FUNC INT SCREEN_HEIGHT(){
RETURN(SCREEN()[0d2])
}

FUNC INT: WINDOW_WIDTH(INT: handle){
FUNC INT WINDOW_WIDTH(INT handle){
RETURN(WINDOW(handle)[0d1])
}

FUNC INT: WINDOW_HEIGHT(INT: handle){
FUNC INT WINDOW_HEIGHT(INT handle){
RETURN(WINDOW(handle)[0d2])
}
56 changes: 28 additions & 28 deletions lib/std/image/init.pre
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ EXTEND(EXTENSION: image)

IMPORT(path)

FUNC TNS: LOAD(STR: img_path){
STR: ext = path.EXTNAME(img_path)
FUNC TNS LOAD(STR img_path){
STR ext = path.EXTNAME(img_path)
IF(EQ(ext, "png")){
RETURN(LOAD_PNG(img_path))
} ELSEIF (OR(EQ(ext, "jpg"),EQ(ext, "jpeg"))){
Expand All @@ -23,70 +23,70 @@ FUNC TNS: LOAD(STR: img_path){
}
}

FUNC INT: WIDTH(TNS: img){
FUNC INT WIDTH(TNS img){
RETURN(TLEN(img, 0d1))
}

FUNC INT: HEIGHT(TNS: img){
FUNC INT HEIGHT(TNS img){
RETURN(TLEN(img, 0d2))
}

FUNC INT: CHANNELS(TNS: img){
FUNC INT CHANNELS(TNS img){
RETURN(TLEN(img, 0d3))
}

FUNC TNS: R(TNS: img){
FUNC TNS R(TNS img){
RETURN(img[*, *, 0d1])
}

FUNC TNS: G(TNS: img){
FUNC TNS G(TNS img){
RETURN(img[*, *, 0d2])
}

FUNC TNS: B(TNS: img){
FUNC TNS B(TNS img){
RETURN(img[*, *, 0d3])
}

FUNC TNS: A(TNS: img){
FUNC TNS A(TNS img){
RETURN(img[*, *, 0d4])
}

FUNC TNS: PIXEL(TNS: img, INT: x, INT: y){
FUNC TNS PIXEL(TNS img, INT x, INT y){
RETURN(img[x, y, *])
}

FUNC INT: PIXEL_R(TNS: img, INT: x, INT: y){
FUNC INT PIXEL_R(TNS img, INT x, INT y){
RETURN(img[x, y, 0d1])
}

FUNC INT: PIXEL_G(TNS: img, INT: x, INT: y){
FUNC INT PIXEL_G(TNS img, INT x, INT y){
RETURN(img[x, y, 0d2])
}

FUNC INT: PIXEL_B(TNS: img, INT: x, INT: y){
FUNC INT PIXEL_B(TNS img, INT x, INT y){
RETURN(img[x, y, 0d3])
}

FUNC INT: PIXEL_A(TNS: img, INT: x, INT: y){
FUNC INT PIXEL_A(TNS img, INT x, INT y){
RETURN(img[x, y, 0d4])
}

FUNC TNS: FLIP_V(TNS: img){
FUNC TNS FLIP_V(TNS img){
RETURN(TFLIP(img, 0d1))
}

FUNC TNS: FLIP_H(TNS: img){
FUNC TNS FLIP_H(TNS img){
RETURN(TFLIP(img, 0d2))
}

FUNC TNS: INVERT(TNS: img){
TNS: return = MSUB(TNS(SHAPE(img), 0xFF), img)
FUNC TNS INVERT(TNS img){
TNS return = MSUB(TNS(SHAPE(img), 0xFF), img)
return[*, *, 0d4] = img[*, *, 0d4] ! Preserve alpha
POP(return)
}

FUNC TNS: RECT(TNS: img, INT: x, INT: y, INT: width, INT: height, TNS: color, INT: fill, INT: thickness){
TNS: pts = [ ^
FUNC TNS RECT(TNS img, INT x, INT y, INT width, INT height, TNS color, INT fill, INT thickness){
TNS pts = [ ^
[x, y], ^
[ADD(x, SUB(width, 0d1)), y], ^
[ADD(x, SUB(width, 0d1)), ADD(y, SUB(height, 0d1))], ^
Expand All @@ -96,37 +96,37 @@ FUNC TNS: RECT(TNS: img, INT: x, INT: y, INT: width, INT: height, TNS: color, IN
RETURN(POLYGON(img, pts, color, fill, thickness))
}

FUNC TNS: RECTANGLE(TNS: img, INT: x, INT: y, INT: width, INT: height, TNS: color, INT: fill, INT: thickness){
FUNC TNS RECTANGLE(TNS img, INT x, INT y, INT width, INT height, TNS color, INT fill, INT thickness){
RETURN(RECT(img, x, y, width, height, color, fill, thickness))
}

FUNC TNS: FILL_RECT(TNS: img, INT: x, INT: y, INT: width, INT: height, TNS: color){
FUNC TNS FILL_RECT(TNS img, INT x, INT y, INT width, INT height, TNS color){
RETURN(RECT(img, x, y, width, height, color, 0d1, 0d1))
}

FUNC TNS: FILL_ELLIPSE(TNS: img, TNS: center, INT: rx, INT: ry, TNS: color){
FUNC TNS FILL_ELLIPSE(TNS img, TNS center, INT rx, INT ry, TNS color){
RETURN(ELLIPSE(img, center, rx, ry, color, 0d1, 0d1))
}

FUNC TNS: SQUARE(TNS: img, INT: x, INT: y, INT: size, TNS: color, INT: fill, INT: thickness){
FUNC TNS SQUARE(TNS img, INT x, INT y, INT size, TNS color, INT fill, INT thickness){
RETURN(RECT(img, x, y, size, size, color, fill, thickness))
}

FUNC TNS: CIRCLE(TNS: img, TNS: center, INT: radius, TNS: color, INT: fill, INT: thickness){
FUNC TNS CIRCLE(TNS img, TNS center, INT radius, TNS color, INT fill, INT thickness){
RETURN(ELLIPSE(img, center, radius, radius, color, fill, thickness))
}

FUNC TNS: CROP(TNS: img, TNS: corners){
FUNC TNS CROP(TNS img, TNS corners){
IF(NEQ(SHAPE(corners), [0d4, 0d2])){
THROW("CROP corners must be a 0d4 by 0d2 tensor: [[tl_x, tl_y], [tr_x, tr_y], [bl_x, bl_y], [br_x, br_y]]")
}
RETURN(img[MIN(corners[*, 0d1])-MAX(corners[*, 0d1]), MIN(corners[*, 0d2])-MAX(corners[*, 0d2]), *])
}

FUNC BOOL: SHOW(TNS: img){
FUNC BOOL SHOW(TNS img){
! Save the image to the provided path and open it with the system default
! viewer on Windows. `img_path` is treated as the target file path.
STR: img_path = "C:/Windows/Temp/tmp_img.png"
STR img_path = "C:/Windows/Temp/tmp_img.png"
SAVE_PNG(img, img_path, 0d0)
! ShellExecuteW(hwnd, operation, file, params, dir, showcmd)
! Use NULL hwnd (0), operation "open", empty params and dir, showcmd=1
Expand Down
Loading
Loading