Add MEASURE fix List operators

This commit is contained in:
zongor 2024-12-07 21:19:43 -05:00
parent 1b26f3e65a
commit 8edcea969e
4 changed files with 160 additions and 121 deletions

View File

@ -1 +1 @@
(1 2 3 4 "test this" pi(*test*)) empty? disp ("test this" (*test*) ) pi cons 2 cons 1 cons 4 { split exch disp newline } repeat

2
tcp3333 Executable file
View File

@ -0,0 +1,2 @@
#!/bin/rc
exec bin/varaq examples/http_read.vqe >>[2]/sys/log/www

View File

@ -352,14 +352,14 @@ func Interpret(code Expr, argv []string, w io.Writer) error {
return fmt.Errorf("cannot `split` not a list @%v", idx) return fmt.Errorf("cannot `split` not a list @%v", idx)
} }
case CONS: case CONS:
list, e := pop()
if e != nil {
return e
}
o, eo := pop() o, eo := pop()
if eo != nil { if eo != nil {
return eo return eo
} }
list, e := pop()
if e != nil {
return e
}
if list.Tok == LIST { if list.Tok == LIST {
list.Exprs = append(list.Exprs, o) list.Exprs = append(list.Exprs, o)
push(list) push(list)
@ -378,6 +378,16 @@ func Interpret(code Expr, argv []string, w io.Writer) error {
} else { } else {
return fmt.Errorf("cannot `shatter` not a list @%v", idx) return fmt.Errorf("cannot `shatter` not a list @%v", idx)
} }
case MEASURE:
list, e := pop()
if e != nil {
return e
}
if list.Tok == LIST {
push(Expr{NUMBER, nil, float64(len(list.Exprs)), 0})
} else {
return fmt.Errorf("cannot `measure` not a list @%v", idx)
}
case EMPTY: case EMPTY:
list, e := pop() list, e := pop()
if e != nil { if e != nil {
@ -1014,11 +1024,35 @@ func Interpret(code Expr, argv []string, w io.Writer) error {
fmt.Fprintf(w, "%v", a.Value) fmt.Fprintf(w, "%v", a.Value)
} }
case LISTEN: case LISTEN:
// FIXME: should there be a way to do this in wasm??
if runtime.GOARCH == "wasm" { if runtime.GOARCH == "wasm" {
return nil // In WASM mode fetch does a fetch request from a foreign website
v1, e := pop()
if e != nil {
return e
} }
if v1.Tok == STRING {
url := v1.Value.(string)
resp, err := http.Get(url)
if err != nil {
// we will get an error at this stage if the request fails, such as if the
// requested URL is not found, or if the server is not reachable.
return err
}
defer resp.Body.Close()
// print the response
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
push(Expr{STRING, nil, string(data), 0})
} else {
return fmt.Errorf("cannot `streq?` value is not a string @%v", idx)
}
} else {
var str string var str string
s.Scan() s.Scan()
@ -1028,6 +1062,7 @@ func Interpret(code Expr, argv []string, w io.Writer) error {
return s.Err() return s.Err()
} }
push(Expr{STRING, nil, str, 0}) push(Expr{STRING, nil, str, 0})
}
case COMPLAIN: case COMPLAIN:
a, e := popExpr() a, e := popExpr()
if e != nil { if e != nil {

View File

@ -4,109 +4,110 @@ type TokenType int64
const ( const (
UNDEFINED TokenType = iota UNDEFINED TokenType = iota
IDENTIFIER IDENTIFIER // id
STRING STRING // string
NUMBER NUMBER // float
BOOLEAN BOOLEAN // bool
LIST LIST // list
SCRIPT SCRIPT // script
FUNCTION FUNCTION // function
ERROR ERROR // error
LEFTPAREN LEFTPAREN // (
RIGHTPAREN RIGHTPAREN // )
LEFTBRACE LEFTBRACE // {
RIGHTBRACE RIGHTBRACE // }
TILDE TILDE // The ~ operator is a special form, as it is not a postfix operator. When the interpreter encounters a ~, it pushes the next token on the stack as is regardless of whether it is a defined name.
SLASH SLASH // /
STAR STAR // *
FALSE FALSE // false
TRUE TRUE // true
PI PI // 3.14159
E E // 2.718
EOF EOF // end of file
POP POP // Pops and discards the top item on the stack. The literal meaning is discard.
DUP DUP // Duplicates the top object on the stack.
EXCH EXCH // Inverts the order of the top two objects on the stack.
CLEAR CLEAR // Empties the stack.
REMEMBER REMEMBER // Puts a flag (like PostScripts mark) on the stack. The internal representation of the flag is not available to the programmer.
FORGET FORGET // Clears the stack down to the flag and pops the flag. If there is no flag present, the stack is emptied completely.
DUMP DUMP // Prints the contents of the operand stack to STDOUT without changing them.
NAME NAME // Associates obj with id and places it in the system lookup space. Conventionally used to associate new operator names with procedure objects.
SET SET // Reassigns the value of a value already in the system lookup space. Used primarily for variable assignments.
IFYES IFYES //
IFNO IFNO //
CHOOSE CHOOSE //
EVAL EVAL //
ESCAPE ESCAPE //
REPEAT REPEAT //
SPLIT SPLIT //
CONS CONS //
SHATTER SHATTER //
EMPTY MEASURE //
COMPOSE EMPTY //
STREQ COMPOSE //
STRCUT STREQ //
STRMEASURE STRCUT //
STRTIE STRMEASURE //
EXPLODE STRTIE //
ADD EXPLODE //
SUB ADD //
MUL SUB //
DIV MUL //
IDIV DIV //
MOD IDIV //
POW MOD //
SQRT POW //
ADD1 SQRT //
SUB1 ADD1 //
SIN SUB1 //
COS SIN //
TAN COS //
ATAN TAN //
LN ATAN //
LOG LN //
LOG3 LOG //
CLIP LOG3 //
SMOOTH CLIP //
HOWMUCH SMOOTH //
SETRAND HOWMUCH //
RAND SETRAND //
NUMBERIZE RAND //
ISOLATE NUMBERIZE //
MIX ISOLATE //
CONTRADICT MIX //
COMPL CONTRADICT //
SHIFTRIGHT COMPL //
SHIFTLEFT SHIFTRIGHT //
GT SHIFTLEFT //
LT GT //
EQ LT //
GE EQ //
LE GE //
NE LE //
NULL NE //
NEGATIVE NULL //
ISNULL NEGATIVE //
ISINT ISNULL //
ISNUMBER ISINT //
AND ISNUMBER //
OR AND //
XOR OR //
DISP XOR //
LISTEN DISP //
COMPLAIN LISTEN //
NEWLINE COMPLAIN //
TAB NEWLINE //
WHEREAMI TAB //
VERSION WHEREAMI //
ARGV VERSION //
TIME ARGV //
GARBAGECOLLECT TIME //
OVER GARBAGECOLLECT //
ROT OVER //
DEPTH ROT //
SERVEHTTP DEPTH //
READALL SERVEHTTP //
READALL //
) )
var tokens = [...]string{ var tokens = [...]string{
@ -148,6 +149,7 @@ var tokens = [...]string{
SPLIT: "SPLIT", SPLIT: "SPLIT",
CONS: "CONS", CONS: "CONS",
SHATTER: "SHATTER", SHATTER: "SHATTER",
MEASURE: "MEASURE",
EMPTY: "EMPTY?", EMPTY: "EMPTY?",
COMPOSE: "COMPOSE", COMPOSE: "COMPOSE",
STREQ: "STREQ?", STREQ: "STREQ?",