diff options
Diffstat (limited to 'generate.go')
-rw-r--r-- | generate.go | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/generate.go b/generate.go index 5701cb1..51eb7c0 100644 --- a/generate.go +++ b/generate.go @@ -128,6 +128,14 @@ func generateStatement(stmt statementExpr, w io.Writer) error { return generateMutStmt(s, false, w) case *assignStmt: return generateAssignStmt(s, w) + case *addAssignStmt: + return generateAddAssignStmt(s, w) + case *subAssignStmt: + return generateSubAssignStmt(s, w) + case *mulAssignStmt: + return generateMulAssignStmt(s, w) + case *divAssignStmt: + return generateDivAssignStmt(s, w) } return nil @@ -195,6 +203,94 @@ func generateAssignStmt(stmt *assignStmt, w io.Writer) error { return nil } +func generateAddAssignStmt(stmt *addAssignStmt, w io.Writer) error { + ok, mutable := isDeclared(stmt.name, false) + if !ok { + return errUndeclared{name: stmt.name, line: stmt.line()} + } + if !mutable { + return errImmutable{name: stmt.name, line: stmt.line()} + } + + value, err := stmt.value.generate(w) + if err != nil { + return err + } + + in, out := allocReg(), allocReg() + + fmt.Fprintf(w, "%s =w loadl %%%s\n", in, stmt.name) + fmt.Fprintf(w, "%s =w add %s, %s\n", out, in, value) + fmt.Fprintf(w, "storew %s, %%%s\n", out, stmt.name) + return nil +} + +func generateSubAssignStmt(stmt *subAssignStmt, w io.Writer) error { + ok, mutable := isDeclared(stmt.name, false) + if !ok { + return errUndeclared{name: stmt.name, line: stmt.line()} + } + if !mutable { + return errImmutable{name: stmt.name, line: stmt.line()} + } + + value, err := stmt.value.generate(w) + if err != nil { + return err + } + + in, out := allocReg(), allocReg() + + fmt.Fprintf(w, "%s =w loadl %%%s\n", in, stmt.name) + fmt.Fprintf(w, "%s =w sub %s, %s\n", out, in, value) + fmt.Fprintf(w, "storew %s, %%%s\n", out, stmt.name) + return nil +} + +func generateMulAssignStmt(stmt *mulAssignStmt, w io.Writer) error { + ok, mutable := isDeclared(stmt.name, false) + if !ok { + return errUndeclared{name: stmt.name, line: stmt.line()} + } + if !mutable { + return errImmutable{name: stmt.name, line: stmt.line()} + } + + value, err := stmt.value.generate(w) + if err != nil { + return err + } + + in, out := allocReg(), allocReg() + + fmt.Fprintf(w, "%s =w loadl %%%s\n", in, stmt.name) + fmt.Fprintf(w, "%s =w mul %s, %s\n", out, in, value) + fmt.Fprintf(w, "storew %s, %%%s\n", out, stmt.name) + return nil +} + +func generateDivAssignStmt(stmt *divAssignStmt, w io.Writer) error { + ok, mutable := isDeclared(stmt.name, false) + if !ok { + return errUndeclared{name: stmt.name, line: stmt.line()} + } + if !mutable { + return errImmutable{name: stmt.name, line: stmt.line()} + } + + value, err := stmt.value.generate(w) + if err != nil { + return err + } + + in, out := allocReg(), allocReg() + + fmt.Fprintf(w, "%s =w loadl %%%s\n", in, stmt.name) + fmt.Fprintf(w, "%s =w div %s, %s\n", out, in, value) + fmt.Fprintf(w, "storew %s, %%%s\n", out, stmt.name) + return nil +} + func (e *equalityExpr) generate(w io.Writer) (string, error) { lhs, err := e.lhs.generate(w) if err != nil { |