add initial servehttp
This commit is contained in:
parent
ec4f3c8341
commit
98617309c4
|
@ -10,7 +10,7 @@
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "main.go",
|
"program": "main.go",
|
||||||
"args": ["examples/test.vqe"]
|
"args": ["examples/http_hello_world.vqe"]
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"<!DOCTYPE html>" disp newline
|
||||||
|
"<html>" disp newline
|
||||||
|
"<body>" disp newline
|
||||||
|
"<h1>nuqneH 'u'?</h1>" disp newline
|
||||||
|
"</body>" disp newline
|
||||||
|
"</html>" disp
|
||||||
|
} ":3333" servehttp
|
|
@ -20,8 +20,8 @@ func main() {
|
||||||
|
|
||||||
func repl() {
|
func repl() {
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
fmt.Print("> ")
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
|
fmt.Print("> ")
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
return
|
return
|
||||||
|
@ -30,7 +30,6 @@ func repl() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%v\n", err)
|
fmt.Printf("%v\n", err)
|
||||||
}
|
}
|
||||||
fmt.Print("> ")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ func interpret(src string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
code := varaq.Parse(tokens)
|
code := varaq.Parse(tokens)
|
||||||
err = varaq.Interpret(code, os.Args[1:])
|
err = varaq.Interpret(code, os.Args[1:], os.Stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%v\n", err)
|
fmt.Printf("%v\n", err)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -3,9 +3,11 @@ package varaq
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -46,14 +48,14 @@ func pop() (Expr, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func identifierToObj(c Expr, idx int, argv []string) error {
|
func identifierToObj(c Expr, idx int, argv []string, w io.Writer) error {
|
||||||
k, k_ok := c.Value.(string)
|
k, k_ok := c.Value.(string)
|
||||||
if k_ok {
|
if k_ok {
|
||||||
o := get(k)
|
o := get(k)
|
||||||
if o.Tok == UNDEFINED {
|
if o.Tok == UNDEFINED {
|
||||||
return fmt.Errorf("identifier %s undefined @%v", k, idx)
|
return fmt.Errorf("identifier %s undefined @%v", k, idx)
|
||||||
} else if o.Tok == FUNCTION {
|
} else if o.Tok == FUNCTION {
|
||||||
e := Interpret(o, argv)
|
e := Interpret(o, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
if e == fmt.Errorf("escape") {
|
if e == fmt.Errorf("escape") {
|
||||||
return nil
|
return nil
|
||||||
|
@ -70,8 +72,8 @@ func identifierToObj(c Expr, idx int, argv []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Expr) idToExpr(idx int, argv []string) (Expr, error) {
|
func (c Expr) idToExpr(idx int, argv []string, w io.Writer) (Expr, error) {
|
||||||
e := identifierToObj(c, idx, argv)
|
e := identifierToObj(c, idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return Expr{UNDEFINED, nil, nil, 0}, e
|
return Expr{UNDEFINED, nil, nil, 0}, e
|
||||||
}
|
}
|
||||||
|
@ -84,8 +86,8 @@ func (c Expr) idToExpr(idx int, argv []string) (Expr, error) {
|
||||||
return vv, nil
|
return vv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Expr) idToS(idx int, argv []string) (string, error) {
|
func (c Expr) idToS(idx int, argv []string, w io.Writer) (string, error) {
|
||||||
v, e := c.idToExpr(idx, argv)
|
v, e := c.idToExpr(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return "", e
|
return "", e
|
||||||
}
|
}
|
||||||
|
@ -93,13 +95,13 @@ func (c Expr) idToS(idx int, argv []string) (string, error) {
|
||||||
return fmt.Sprintf("%b", v.Value), nil
|
return fmt.Sprintf("%b", v.Value), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func popArgs(idx int, argv []string) (Expr, Expr, error) {
|
func popArgs(idx int, argv []string, w io.Writer) (Expr, Expr, error) {
|
||||||
b, e := pop()
|
b, e := pop()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
||||||
}
|
}
|
||||||
if b.Tok == IDENTIFIER {
|
if b.Tok == IDENTIFIER {
|
||||||
b, e = b.idToExpr(idx, argv)
|
b, e = b.idToExpr(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,7 @@ func popArgs(idx int, argv []string) (Expr, Expr, error) {
|
||||||
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
||||||
}
|
}
|
||||||
if a.Tok == IDENTIFIER {
|
if a.Tok == IDENTIFIER {
|
||||||
a, e = a.idToExpr(idx, argv)
|
a, e = a.idToExpr(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
return Expr{UNDEFINED, nil, nil, 0}, Expr{UNDEFINED, nil, nil, 0}, e
|
||||||
}
|
}
|
||||||
|
@ -118,7 +120,7 @@ func popArgs(idx int, argv []string) (Expr, Expr, error) {
|
||||||
return a, b, nil
|
return a, b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Interpret(code Expr, argv []string) error {
|
func Interpret(code Expr, argv []string, w io.Writer) error {
|
||||||
for idx, c := range code.Exprs {
|
for idx, c := range code.Exprs {
|
||||||
switch c.Tok {
|
switch c.Tok {
|
||||||
case NUMBER:
|
case NUMBER:
|
||||||
|
@ -170,33 +172,6 @@ func Interpret(code Expr, argv []string) error {
|
||||||
|
|
||||||
push(stack[n-2])
|
push(stack[n-2])
|
||||||
stack = append(stack[:n-2], stack[n-3:]...)
|
stack = append(stack[:n-2], stack[n-3:]...)
|
||||||
case PICK:
|
|
||||||
n := len(stack) - 1
|
|
||||||
a, e := pop()
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
if a.Tok == IDENTIFIER {
|
|
||||||
a = get(a.Value.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Tok == NUMBER {
|
|
||||||
idx := int(a.Value.(float64))
|
|
||||||
|
|
||||||
if idx <= 0 {
|
|
||||||
return fmt.Errorf("`pick`: index must be a positive nonzero value")
|
|
||||||
}
|
|
||||||
if n-idx < 0 {
|
|
||||||
return fmt.Errorf("`pick`: stack underflow")
|
|
||||||
}
|
|
||||||
if idx > n {
|
|
||||||
return fmt.Errorf("`pick`: stack overflow")
|
|
||||||
}
|
|
||||||
push(stack[n-idx])
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("cannot `pick` index is not a number @%v", idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
case DEPTH:
|
case DEPTH:
|
||||||
push(Expr{NUMBER, nil, float64(len(stack)), 0})
|
push(Expr{NUMBER, nil, float64(len(stack)), 0})
|
||||||
case CLEAR:
|
case CLEAR:
|
||||||
|
@ -206,7 +181,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
if idx-1 >= 0 && code.Exprs[idx-1].Tok == TILDE {
|
if idx-1 >= 0 && code.Exprs[idx-1].Tok == TILDE {
|
||||||
push(c)
|
push(c)
|
||||||
} else {
|
} else {
|
||||||
e := identifierToObj(c, idx, argv)
|
e := identifierToObj(c, idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -229,9 +204,9 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
case DUMP:
|
case DUMP:
|
||||||
for n := len(stack) - 1; n >= 0; n-- {
|
for n := len(stack) - 1; n >= 0; n-- {
|
||||||
fmt.Println(stack[n])
|
fmt.Fprintf(w, "%v\n", stack[n])
|
||||||
}
|
}
|
||||||
fmt.Println("=== end of dump ===")
|
fmt.Fprintf(w, "=== end of dump ===\n")
|
||||||
case NAME:
|
case NAME:
|
||||||
fun, e := pop()
|
fun, e := pop()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -273,7 +248,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
if fun.Tok == FUNCTION && logical.Tok == BOOLEAN {
|
if fun.Tok == FUNCTION && logical.Tok == BOOLEAN {
|
||||||
if logical.Value.(bool) {
|
if logical.Value.(bool) {
|
||||||
Interpret(fun, argv)
|
Interpret(fun, argv, w)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot `ifyes` not a function or bool @%v", idx)
|
return fmt.Errorf("cannot `ifyes` not a function or bool @%v", idx)
|
||||||
|
@ -289,7 +264,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
if fun.Tok == FUNCTION && logical.Tok == BOOLEAN {
|
if fun.Tok == FUNCTION && logical.Tok == BOOLEAN {
|
||||||
if !logical.Value.(bool) {
|
if !logical.Value.(bool) {
|
||||||
Interpret(fun, argv)
|
Interpret(fun, argv, w)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot `ifno` not a function or bool @%v", idx)
|
return fmt.Errorf("cannot `ifno` not a function or bool @%v", idx)
|
||||||
|
@ -311,7 +286,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
if fun.Tok == FUNCTION {
|
if fun.Tok == FUNCTION {
|
||||||
Interpret(fun, argv)
|
Interpret(fun, argv, w)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot `eval` not a function @%v", idx)
|
return fmt.Errorf("cannot `eval` not a function @%v", idx)
|
||||||
}
|
}
|
||||||
|
@ -328,7 +303,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
if fun.Tok == FUNCTION && count.Tok == NUMBER {
|
if fun.Tok == FUNCTION && count.Tok == NUMBER {
|
||||||
for n := int64(0); n < int64(count.Value.(float64)); n++ {
|
for n := int64(0); n < int64(count.Value.(float64)); n++ {
|
||||||
err := Interpret(fun, argv)
|
err := Interpret(fun, argv, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -436,7 +411,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
var v2_s string
|
var v2_s string
|
||||||
|
|
||||||
if v1.Tok == IDENTIFIER {
|
if v1.Tok == IDENTIFIER {
|
||||||
v1_s, e = v1.idToS(idx, argv)
|
v1_s, e = v1.idToS(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -462,7 +437,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if v2.Tok == IDENTIFIER {
|
if v2.Tok == IDENTIFIER {
|
||||||
v2_s, e = v2.idToS(idx, argv)
|
v2_s, e = v2.idToS(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -530,7 +505,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ADD:
|
case ADD:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -541,7 +516,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return fmt.Errorf("cannot `add` values are not numbers @%v", idx)
|
return fmt.Errorf("cannot `add` values are not numbers @%v", idx)
|
||||||
}
|
}
|
||||||
case SUB:
|
case SUB:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -552,7 +527,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return fmt.Errorf("cannot `sub` values are not numbers @%v", idx)
|
return fmt.Errorf("cannot `sub` values are not numbers @%v", idx)
|
||||||
}
|
}
|
||||||
case MUL:
|
case MUL:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -563,7 +538,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return fmt.Errorf("cannot `mul` values are not numbers @%v", idx)
|
return fmt.Errorf("cannot `mul` values are not numbers @%v", idx)
|
||||||
}
|
}
|
||||||
case DIV:
|
case DIV:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -574,7 +549,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return fmt.Errorf("cannot `div` values are not numbers @%v", idx)
|
return fmt.Errorf("cannot `div` values are not numbers @%v", idx)
|
||||||
}
|
}
|
||||||
case IDIV:
|
case IDIV:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -585,7 +560,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return fmt.Errorf("cannot `idiv` values are not numbers @%v", idx)
|
return fmt.Errorf("cannot `idiv` values are not numbers @%v", idx)
|
||||||
}
|
}
|
||||||
case MOD:
|
case MOD:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -596,7 +571,7 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return fmt.Errorf("cannot `mod` values are not numbers @%v", idx)
|
return fmt.Errorf("cannot `mod` values are not numbers @%v", idx)
|
||||||
}
|
}
|
||||||
case POW:
|
case POW:
|
||||||
a, b, e := popArgs(idx, argv)
|
a, b, e := popArgs(idx, argv, w)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -1215,15 +1190,15 @@ func Interpret(code Expr, argv []string) error {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
if a.Tok == IDENTIFIER {
|
if a.Tok == IDENTIFIER {
|
||||||
fmt.Printf("%v\n", get(a.Value.(string)))
|
fmt.Fprintf(w, "%v", get(a.Value.(string)))
|
||||||
} else if a.Tok == NUMBER {
|
} else if a.Tok == NUMBER {
|
||||||
if a.Value.(float64) == float64(int64(a.Value.(float64))) {
|
if a.Value.(float64) == float64(int64(a.Value.(float64))) {
|
||||||
fmt.Printf("%d\n", int64(a.Value.(float64)))
|
fmt.Fprintf(w, "%d", int64(a.Value.(float64)))
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%f\n", a.Value.(float64))
|
fmt.Fprintf(w, "%f", a.Value.(float64))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%v\n", a.Value)
|
fmt.Fprintf(w, "%v", a.Value)
|
||||||
}
|
}
|
||||||
case LISTEN:
|
case LISTEN:
|
||||||
var str string
|
var str string
|
||||||
|
@ -1245,9 +1220,9 @@ func Interpret(code Expr, argv []string) error {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%v", a.Value)
|
fmt.Fprintf(os.Stderr, "%v", a.Value)
|
||||||
case NEWLINE:
|
case NEWLINE:
|
||||||
fmt.Println()
|
fmt.Fprintf(w, "\n")
|
||||||
case TAB:
|
case TAB:
|
||||||
fmt.Println("\t")
|
fmt.Fprintf(w, "\t")
|
||||||
case WHEREAMI:
|
case WHEREAMI:
|
||||||
conn, e := net.Dial("udp", "8.8.8.8:80")
|
conn, e := net.Dial("udp", "8.8.8.8:80")
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -1257,9 +1232,31 @@ func Interpret(code Expr, argv []string) error {
|
||||||
|
|
||||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||||
|
|
||||||
fmt.Println(localAddr.IP.String())
|
fmt.Fprintf(w, "%s\n", localAddr.IP.String())
|
||||||
|
case SERVEHTTP:
|
||||||
|
str, e := pop()
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
if str.Tok != STRING {
|
||||||
|
return fmt.Errorf("cannot `servehttp` exptected a string for the port @%v", idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.ListenAndServe(str.Value.(string), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
fun, e := pop()
|
||||||
|
if e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if fun.Tok == FUNCTION {
|
||||||
|
Interpret(fun, nil, w)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
case VERSION:
|
case VERSION:
|
||||||
fmt.Println("var'aq -- 0.9.1 Martoq")
|
fmt.Fprintf(w, "var'aq -- 0.9.1 Martoq")
|
||||||
case ARGV:
|
case ARGV:
|
||||||
arg := Expr{LIST, make([]Expr, 0), nil, 0}
|
arg := Expr{LIST, make([]Expr, 0), nil, 0}
|
||||||
for _, v := range argv {
|
for _, v := range argv {
|
||||||
|
|
|
@ -181,8 +181,7 @@ var keywords = map[string]TokenType{
|
||||||
"QI": OVER,
|
"QI": OVER,
|
||||||
"depth": DEPTH,
|
"depth": DEPTH,
|
||||||
"juv": DEPTH,
|
"juv": DEPTH,
|
||||||
"pick": PICK,
|
"servehttp": SERVEHTTP,
|
||||||
"woH": PICK,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isDigit(s string) bool {
|
func isDigit(s string) bool {
|
||||||
|
|
|
@ -105,7 +105,7 @@ const (
|
||||||
OVER
|
OVER
|
||||||
ROT
|
ROT
|
||||||
DEPTH
|
DEPTH
|
||||||
PICK
|
SERVEHTTP
|
||||||
)
|
)
|
||||||
|
|
||||||
var tokens = [...]string{
|
var tokens = [...]string{
|
||||||
|
@ -210,7 +210,7 @@ var tokens = [...]string{
|
||||||
OVER: "OVER",
|
OVER: "OVER",
|
||||||
ROT: "ROT",
|
ROT: "ROT",
|
||||||
DEPTH: "DEPTH",
|
DEPTH: "DEPTH",
|
||||||
PICK: "PICK",
|
SERVEHTTP: "SERVEHTTP",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me TokenType) String() string {
|
func (me TokenType) String() string {
|
||||||
|
|
Loading…
Reference in New Issue