Skip to content

Commit

Permalink
Merge pull request #2104 from xushiwei/q
Browse files Browse the repository at this point in the history
gauss.pseudo
  • Loading branch information
xushiwei authored Feb 14, 2025
2 parents 37d1083 + 7214b2c commit 4ad6eb0
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 8 deletions.
12 changes: 12 additions & 0 deletions demo/gop-parser/pseudo/gauss.pseudo
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
DECLARE n : INTEGER
DECLARE i : INTEGER
DECLARE sum : INTEGER
OUTPUT "please input n:"
INPUT n
i <- 1
sum <- 0
WHILE i <= n DO
sum <- sum + i
i <- i + 1
ENDWHILE
OUTPUT sum
7 changes: 2 additions & 5 deletions demo/gop-parser/pseudo/main.gop
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import "os"

func NewState() *state {
return &state{vars: {}, consts: {}}
}

func exec(code string) {
lines := code.split("\n")
stmts := parse(lines)
newState.exec(stmts)
s := state.new()
s.exec(stmts)
}

if len(os.Args) < 2 {
Expand Down
199 changes: 196 additions & 3 deletions demo/gop-parser/pseudo/state.gox
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import (
"fmt"
"gop/ast"
"gop/token"
"math"
Expand All @@ -10,6 +11,10 @@ var (
consts map[string]any
)

func .new() *state {
return &state{vars: {}, consts: {}}
}

func exec(stmts []Stmt) {
for _, stmt := range stmts {
execStmt(stmt)
Expand Down Expand Up @@ -74,7 +79,14 @@ func execOutputStmt(stmt *OutputStmt) {
}

func execInputStmt(stmt *InputStmt) {
panic("todo")
name := stmt.Name
oldv, ok := vars[name]
if !ok {
panic("undefined variable `${name}`")
}
v := reflect.new(reflect.typeOf(oldv))
fmt.scanln(v.Interface())!
vars[name] = v.elem.Interface()
}

func execIfStmt(stmt *IfStmt) {
Expand Down Expand Up @@ -123,9 +135,24 @@ func calc(e ast.Expr) any {
return calcMul(calc(e.X), calc(e.Y))
case token.QUO:
return calcQuo(calc(e.X), calc(e.Y))
case token.EQL:
return calcEQL(calc(e.X), calc(e.Y))
case token.NEQ:
return calcNEQ(calc(e.X), calc(e.Y))
case token.LSS:
return calcLSS(calc(e.X), calc(e.Y))
case token.GTR:
return calcGTR(calc(e.Y), calc(e.X))
case token.LEQ:
return calcLEQ(calc(e.X), calc(e.Y))
case token.GEQ:
return calcGEQ(calc(e.Y), calc(e.X))
default:
panic("unknown binary operator ${e.Op}")
}
case *ast.CallExpr:
switch e.Fun.(*ast.Ident).Name {
fn := e.Fun.(*ast.Ident).Name
switch fn {
case "SIN":
x := toFloat(calc(e.Args[0]), "SIN")
return math.Sin(x)
Expand All @@ -136,16 +163,22 @@ func calc(e ast.Expr) any {
x := toFloat(calc(e.Args[0]), "POW")
y := toFloat(calc(e.Args[1]), "POW")
return math.Pow(x, y)
default:
panic("unknown function `${fn}`")
}
case *ast.ParenExpr:
return calc(e.X)
case *ast.UnaryExpr:
switch e.Op {
case token.SUB:
return calcNeg(calc(e.X))
case token.NOT:
return calcNot(calc(e.X))
default:
panic("unknown unary operator ${e.Op}")
}
}
panic("unknown expression")
panic("unknown expression: ${reflect.typeOf(e)}")
}

func calcAdd(a, b any) any {
Expand Down Expand Up @@ -232,6 +265,158 @@ func calcQuo(a, b any) any {
panic("invalid operands of /")
}

func calcLSS(a, b any) any {
switch a := a.(type) {
case int:
switch b := b.(type) {
case int:
return a < b
case float64:
return float64(a) < b
}
case float64:
switch b := b.(type) {
case int:
return a < float64(b)
case float64:
return a < b
}
case string:
if b, ok := b.(string); ok {
return a < b
}
}
panic("invalid operands of <")
}

func calcGTR(a, b any) any {
switch a := a.(type) {
case int:
switch b := b.(type) {
case int:
return a > b
case float64:
return float64(a) > b
}
case float64:
switch b := b.(type) {
case int:
return a > float64(b)
case float64:
return a > b
}
case string:
if b, ok := b.(string); ok {
return a > b
}
}
panic("invalid operands of >")
}

func calcLEQ(a, b any) any {
switch a := a.(type) {
case int:
switch b := b.(type) {
case int:
return a <= b
case float64:
return float64(a) <= b
}
case float64:
switch b := b.(type) {
case int:
return a <= float64(b)
case float64:
return a <= b
}
case string:
if b, ok := b.(string); ok {
return a <= b
}
}
panic("invalid operands of <=")
}

func calcGEQ(a, b any) any {
switch a := a.(type) {
case int:
switch b := b.(type) {
case int:
return a >= b
case float64:
return float64(a) >= b
}
case float64:
switch b := b.(type) {
case int:
return a >= float64(b)
case float64:
return a >= b
}
case string:
if b, ok := b.(string); ok {
return a >= b
}
}
panic("invalid operands of >=")
}

func calcEQL(a, b any) any {
switch a := a.(type) {
case int:
switch b := b.(type) {
case int:
return a == b
case float64:
return float64(a) == b
}
case float64:
switch b := b.(type) {
case int:
return a == float64(b)
case float64:
return a == b
}
case string:
if b, ok := b.(string); ok {
return a == b
}
case bool:
if b, ok := b.(bool); ok {
return a == b
}
}
panic("invalid operands of ==")
}

func calcNEQ(a, b any) any {
switch a := a.(type) {
case int:
switch b := b.(type) {
case int:
return a != b
case float64:
return float64(a) != b
}
case float64:
switch b := b.(type) {
case int:
return a != float64(b)
case float64:
return a != b
}
case string:
if b, ok := b.(string); ok {
return a != b
}
case bool:
if b, ok := b.(bool); ok {
return a != b
}
}
panic("invalid operands of !=")
}

func calcNeg(a any) any {
switch a := a.(type) {
case int:
Expand All @@ -242,6 +427,14 @@ func calcNeg(a any) any {
panic("invalid operand of unary -")
}

func calcNot(a any) any {
switch a := a.(type) {
case bool:
return !a
}
panic("invalid operand of !")
}

func getValue(name string) any {
if v, ok := vars[name]; ok {
return v
Expand Down

0 comments on commit 4ad6eb0

Please sign in to comment.