From a7a15e1193b09414316fea40d6999f47bc0f57d4 Mon Sep 17 00:00:00 2001 From: Himbeer Date: Sun, 1 Sep 2024 11:45:51 +0200 Subject: Add support for arithmetic assignment statements --- generate.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'generate.go') 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 { -- cgit v1.2.3