Adding WIP w/ gemini example.
This commit is contained in:
131
examples/gemini/arrays.fs
Executable file
131
examples/gemini/arrays.fs
Executable file
@ -0,0 +1,131 @@
|
||||
#! /usr/bin/env ueforth
|
||||
|
||||
vocabulary arrays also internals also arrays definitions
|
||||
|
||||
128 constant stack-depth
|
||||
|
||||
( Stack for arrays )
|
||||
create astack stack-depth cells allot
|
||||
variable ap astack ap !
|
||||
: apush ( a -- ) cell ap +! ap @ ! ;
|
||||
: apop ( -- a ) ap @ @ cell negate ap +! ;
|
||||
: top ( -- a ) ap @ @ ;
|
||||
: under ( -- a ) ap @ cell - @ ;
|
||||
|
||||
( Secondary stack for arrays )
|
||||
create arstack stack-depth cells allot
|
||||
variable arp arstack arp !
|
||||
: >a apop cell arp +! arp @ ! ;
|
||||
: a> arp @ @ cell negate arp +! apush ;
|
||||
|
||||
( Array types )
|
||||
0 constant MIXED
|
||||
1 constant STRING
|
||||
2 constant INTEGER
|
||||
3 constant REAL
|
||||
create array-sizes cell , 1 , cell , 4 ,
|
||||
: >esize ( type -- n ) cells array-sizes + @ ;
|
||||
|
||||
\ ref n ^type data...
|
||||
3 cells constant header-size
|
||||
: >type ( a -- a ) -1 cells + ;
|
||||
: >count ( a -- a ) -2 cells + ;
|
||||
: >ref ( a -- a ) -3 cells + ;
|
||||
|
||||
( Size of array data in bytes )
|
||||
: bytes ( a -- n ) dup >type @ >esize swap >count @ * ;
|
||||
|
||||
( Create an uninitialized array )
|
||||
: array ( n type -- a )
|
||||
2dup >esize * header-size + allocate throw header-size + apush
|
||||
top >type ! top >count ! 0 top >ref ! ;
|
||||
|
||||
( Reference counting for arrays )
|
||||
: ref ( a -- ) 1 over >ref +! ;
|
||||
: unref ( a -- )
|
||||
dup 0= if drop exit then
|
||||
-1 over >ref +!
|
||||
dup >ref @ 0< if
|
||||
dup >type @ MIXED = if
|
||||
dup dup >count @ 0 ?do
|
||||
dup @ recurse cell+
|
||||
loop
|
||||
drop
|
||||
then
|
||||
header-size - free throw exit
|
||||
then drop ;
|
||||
|
||||
( Stack manipulation )
|
||||
: adrop ( a: a -- ) apop unref ;
|
||||
: anip ( a: a b -- b ) apop apop unref apush ;
|
||||
: adup ( a: a -- a a ) top ref apush ;
|
||||
: aswap ( a: a b -- b a ) apop apop swap apush apush ;
|
||||
|
||||
( Index into the top of the stack )
|
||||
: a@ ( n a: a -- a: a ) cells top + @ ref adrop apush ;
|
||||
|
||||
( Raw array creation words )
|
||||
: empty ( -- a: a ) 0 MIXED array ;
|
||||
: box ( a: a -- a ) apop 1 MIXED array top ! ;
|
||||
: _s ( a n -- a: a ) dup STRING array top swap cmove ;
|
||||
: _c ( ch -- a: a ) 1 STRING array top c! ;
|
||||
: _i ( n -- a: a ) 1 INTEGER array top ! ;
|
||||
: _f ( f: n -- a: a ) 1 REAL array top sf! ;
|
||||
: _s" postpone s" state @ if postpone _s else _s then ; immediate
|
||||
|
||||
: aconstant create apop , does> @ ref apush ;
|
||||
|
||||
( Convert integer array to floats )
|
||||
: n>f
|
||||
top >count @ REAL array
|
||||
under top top >count @ 0 ?do over @ s>f dup sf! sfloat+ >r cell+ r> loop 2drop anip ;
|
||||
|
||||
( Force integers to real. )
|
||||
: binuminal
|
||||
top >type @ INTEGER = under >type @ REAL = and if n>f then
|
||||
under >type @ INTEGER = top >type @ REAL = and if apop n>f apush then
|
||||
;
|
||||
|
||||
0 value layer
|
||||
: lst ( a -- )
|
||||
layer spaces
|
||||
dup >type @ case
|
||||
MIXED of
|
||||
." [" cr
|
||||
2 +to layer
|
||||
dup >count @ 0 ?do
|
||||
dup @ recurse cell+ cr
|
||||
loop
|
||||
drop
|
||||
-2 +to layer
|
||||
layer spaces ." ]"
|
||||
endof
|
||||
STRING of dup >count @ type endof
|
||||
INTEGER of dup >count @ 0 ?do dup @ . cell+ loop drop endof
|
||||
REAL of dup >count @ 0 ?do dup sf@ f. sfloat+ loop drop endof
|
||||
endcase
|
||||
;
|
||||
: a. ( a -- ) top lst adrop ;
|
||||
|
||||
: catenate ( a: a a -- a ) ( catenate )
|
||||
binuminal
|
||||
top >type @ under >type @ = if
|
||||
under >count @ top >count @ + top >type @ array apop >r
|
||||
under r@ under bytes cmove
|
||||
top r@ under bytes + top bytes cmove
|
||||
under under bytes 0 fill
|
||||
top top bytes 0 fill
|
||||
r> apush anip anip
|
||||
exit
|
||||
then
|
||||
top >type @ MIXED = if apop box apush recurse exit then
|
||||
under >type @ MIXED = if box recurse exit then
|
||||
apop apop 2 MIXED array top cell+ ! top !
|
||||
;
|
||||
: ,c catenate ;
|
||||
|
||||
( Building arrays on the stack. )
|
||||
: [[ ap @ ;
|
||||
: ]] ap @ swap - cell/ empty for aft aswap box aswap ,c then next ;
|
||||
|
||||
previous previous forth definitions
|
||||
63
examples/gemini/gemini.fs
Executable file
63
examples/gemini/gemini.fs
Executable file
@ -0,0 +1,63 @@
|
||||
#! /usr/bin/env ueforth
|
||||
|
||||
needs arrays.fs
|
||||
needs json.fs
|
||||
needs slurp.fs
|
||||
|
||||
vocabulary gemini also json also arrays also gemini definitions
|
||||
|
||||
: askit { a n -- a }
|
||||
{{
|
||||
[[ _s" contents" [[
|
||||
{{
|
||||
[[ _s" parts" [[
|
||||
{{
|
||||
[[ _s" text" a n _s ]]
|
||||
}}
|
||||
]] ]]
|
||||
}}
|
||||
]] ]]
|
||||
}}
|
||||
;
|
||||
|
||||
s" What's the time?" askit >json a.
|
||||
|
||||
0 [IF]
|
||||
HTTPClient
|
||||
NetworkClientSecure.new constant nclient
|
||||
|
||||
: 2constant create , , does> dup cell+ @ swap @ ;
|
||||
|
||||
: slurp-file ( a n -- a n )
|
||||
r/o open-file throw >r
|
||||
r@ file-size throw ( sz )
|
||||
dup 1+ allocate throw swap ( data sz )
|
||||
2dup r@ read-file throw drop
|
||||
r> close-file throw
|
||||
2dup + 0 swap c!
|
||||
;
|
||||
|
||||
s" /spiffs/gemini_cert" slurp-file drop constant cacert
|
||||
s" /spiffs/gemini_url" slurp-file drop constant url
|
||||
s" /spiffs/question" slurp-file 2constant question
|
||||
|
||||
cacert nclient NetworkClientSecure.setCACert
|
||||
." loaded cert:" cr
|
||||
cacert z>s type cr
|
||||
|
||||
HTTPClient.new constant session
|
||||
." created session" cr
|
||||
." URL: " url z>s type cr
|
||||
url nclient session HTTPClient.beginNC ." beginNC: " . cr
|
||||
1 session HTTPClient.setFollowRedirects
|
||||
10 session HTTPClient.setRedirectLimit
|
||||
." set follow redirects and limit of 10" cr
|
||||
." question: " question type
|
||||
z" POST" question session HTTPClient.sendRequest ." POSTED: " . cr
|
||||
|
||||
session HTTPClient.getStreamPtr constant result
|
||||
result NetworkClient.available ." available: " dup . cr
|
||||
|
||||
[THEN]
|
||||
|
||||
previous previous previous forth definitions
|
||||
154
examples/gemini/json.fs
Executable file
154
examples/gemini/json.fs
Executable file
@ -0,0 +1,154 @@
|
||||
#! /usr/bin/env ueforth
|
||||
|
||||
needs arrays.fs
|
||||
|
||||
vocabulary json also internals also arrays also json definitions
|
||||
|
||||
defer getchar
|
||||
-1 value token
|
||||
: skip getchar to token ;
|
||||
|
||||
variable insource
|
||||
variable inlength
|
||||
: in ( a n -- ) inlength ! insource ! skip ;
|
||||
: ingetchar ( -- n )
|
||||
inlength @ 0= if -1 exit then
|
||||
insource @ c@ 1 insource +! -1 inlength +! ;
|
||||
' ingetchar is getchar
|
||||
|
||||
s" DICTIONARY" _s aconstant DICT
|
||||
: {{ [[ DICT ;
|
||||
: }} ]] ;
|
||||
|
||||
: space? ( ch -- f ) dup 8 = over 10 = or over 13 = or swap 32 = or ;
|
||||
: whitespace begin token space? while skip repeat ;
|
||||
: expect ( a n -- ) for aft dup c@ token = assert 1+ skip then next drop ;
|
||||
: sliteral ( a n -- ) postpone $@ dup , zplace ;
|
||||
: e: bl parse sliteral postpone expect ; immediate
|
||||
|
||||
: escaped
|
||||
e: \
|
||||
token skip case
|
||||
[char] " of [char] " _c catenate endof
|
||||
[char] \ of [char] \ _c catenate endof
|
||||
[char] / of [char] / _c catenate endof
|
||||
[char] b of 8 _c catenate endof
|
||||
[char] n of nl _c catenate endof
|
||||
[char] r of 13 _c catenate endof
|
||||
[char] t of 8 _c catenate endof
|
||||
[char] u of 255 _c catenate skip skip skip skip endof
|
||||
-1 throw
|
||||
endcase
|
||||
;
|
||||
|
||||
: jstring
|
||||
e: " s" " _s
|
||||
begin token [char] " <> while
|
||||
token [char] \ = if
|
||||
escaped
|
||||
else
|
||||
token _c catenate
|
||||
skip
|
||||
then
|
||||
repeat
|
||||
e: "
|
||||
;
|
||||
|
||||
defer jvalue
|
||||
|
||||
: jobject
|
||||
e: { whitespace
|
||||
DICT box
|
||||
begin
|
||||
token [char] } = if skip exit then
|
||||
jstring box whitespace e: : whitespace jvalue box
|
||||
catenate box catenate
|
||||
token [char] } = if skip exit then
|
||||
e: , whitespace
|
||||
again
|
||||
e: }
|
||||
;
|
||||
|
||||
: digit? ( -- f ) token [char] 0 >= token [char] 9 <= and ;
|
||||
: jdigit token [char] 0 - skip ;
|
||||
: jinteger digit? assert jdigit
|
||||
begin digit? while 10 * jdigit + repeat ;
|
||||
: jfraction digit? assert 10 * jdigit + >r 1- r>
|
||||
begin digit? while 10 * jdigit + >r 1- r> repeat ;
|
||||
: jnumber
|
||||
token [char] - = if skip -1 else 1 then
|
||||
token [char] 0 = if skip 0 else jinteger then 0 swap
|
||||
token [char] . = if skip jfraction then
|
||||
swap >r * r>
|
||||
token [char] e = token [char] E = or if
|
||||
skip
|
||||
token [char] - = if
|
||||
skip -1
|
||||
else
|
||||
token [char] + = if skip then 1
|
||||
then
|
||||
jinteger * +
|
||||
then
|
||||
dup if 10e s>f f** s>f f* _f else drop _i then
|
||||
;
|
||||
|
||||
: jarray
|
||||
e: [ whitespace
|
||||
0 MIXED array
|
||||
begin
|
||||
token [char] ] = if skip exit then
|
||||
jvalue box catenate whitespace
|
||||
token [char] ] = if skip exit then
|
||||
e: , whitespace
|
||||
again
|
||||
;
|
||||
|
||||
:noname
|
||||
whitespace
|
||||
token case
|
||||
[char] " of jstring endof
|
||||
[char] { of jobject endof
|
||||
[char] [ of jarray endof
|
||||
[char] t of e: true s" true" _s endof
|
||||
[char] f of e: false s" false" _s endof
|
||||
[char] n of e: null s" null" _s endof
|
||||
jnumber
|
||||
endcase
|
||||
whitespace
|
||||
; is jvalue
|
||||
|
||||
: json> ( a -- a ) top top >count @ in jvalue anip ;
|
||||
|
||||
: butlast? ( n -- f ) top >count @ 1- <> ;
|
||||
|
||||
: >json ( a: a -- a )
|
||||
top >type @ case
|
||||
MIXED of
|
||||
top >count @ 1 > if top @ DICT top @ adrop = else 0 then if
|
||||
_s" {" >a top >count @ 1 ?do
|
||||
adup i a@ 0 a@ recurse _s" :" ,c a> aswap ,c >a
|
||||
adup i a@ 1 a@ recurse a> aswap ,c >a
|
||||
i butlast? if a> _s" ," ,c >a then
|
||||
loop a> _s" }" ,c
|
||||
else
|
||||
_s" [" >a top >count @ 0 ?do
|
||||
adup i a@ recurse a> aswap ,c >a
|
||||
i butlast? if a> _s" ," ,c >a then
|
||||
loop a> _s" ]" ,c
|
||||
then
|
||||
endof
|
||||
STRING of [char] " _c >a top top >count @ a> _s ,c [char] " _c ,c endof
|
||||
INTEGER of
|
||||
_s" " >a
|
||||
top >count @ 0 ?do
|
||||
top i cells + @ <# #s #> a> _s" " ,c _s ,c >a
|
||||
loop a> endof
|
||||
REAL of
|
||||
_s" " >a top >count @ 0 ?do
|
||||
top i sfloats + sf@ <# #fs #> a> _s" " ,c _s ,c >a
|
||||
loop a> endof
|
||||
endcase
|
||||
anip
|
||||
;
|
||||
|
||||
previous previous previous forth definitions
|
||||
8
examples/gemini/slurp.fs
Normal file
8
examples/gemini/slurp.fs
Normal file
@ -0,0 +1,8 @@
|
||||
: slurp-file ( a n -- a n )
|
||||
r/o open-file throw >r
|
||||
r@ file-size throw ( sz )
|
||||
dup 1+ allocate throw swap ( data sz )
|
||||
2dup r@ read-file throw drop
|
||||
r> close-file throw
|
||||
2dup + 0 swap c!
|
||||
;
|
||||
Reference in New Issue
Block a user