diff options
author | Himbeer <himbeer@disroot.org> | 2024-09-06 13:19:22 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-09-06 13:56:07 +0200 |
commit | 959599b7bf803a91595375f650245609bf7a338f (patch) | |
tree | 47aafa8d49e00e45c0cb25255c8486eeec763692 | |
parent | 05c620c4d637b73f6b267ed57d5750587ccfd7a3 (diff) |
Add basic type system with only integers
This commit adds static typing with signed and unsigned integers of 8,
16, 32 and 64 bits.
-rw-r--r-- | decl.go | 23 | ||||
-rw-r--r-- | expression.go | 56 | ||||
-rw-r--r-- | generate.go | 312 | ||||
-rw-r--r-- | generate_error.go | 52 | ||||
-rw-r--r-- | parse.go | 16 | ||||
-rw-r--r-- | type.go | 102 |
6 files changed, 501 insertions, 60 deletions
@@ -4,9 +4,26 @@ package main -var funcs = map[string]struct{}{} -var localConsts = map[string]map[string]string{} -var localMuts = map[string]map[string]struct{}{} +var funcs = map[string]*funcInfo{} +var localConsts = map[string]map[string]*localConst{} +var localMuts = map[string]map[string]*localMut{} + +type funcInfo struct { + params []paramInfo + returnType cerType +} + +type paramInfo struct { + typ cerType +} + +type localConst struct { + typ cerType +} + +type localMut struct { + typ cerType +} func isDeclared(name string, toplevel bool) (ok bool, mutable bool) { if toplevel { diff --git a/expression.go b/expression.go index 76cb16b..d042ebf 100644 --- a/expression.go +++ b/expression.go @@ -5,7 +5,6 @@ package main import ( - "fmt" "io" ) @@ -63,19 +62,6 @@ func (p *paramExpr) markExpr() {} func (p *paramExpr) line() int { return p.ln } -func (p *paramExpr) String() string { - if p == nil { - return "" - } - - s := fmt.Sprintf("%s %%%s", p.typ, p.name) - if p.next != nil { - s += p.next.String() - } - - return s -} - type externFuncExpr struct { name string params *signatureExpr @@ -247,6 +233,7 @@ func (r *remAssignStmt) line() int { return r.ln } type exprExpr interface { expression markExprExpr() + cerType() cerType generate(io.Writer) (string, error) } @@ -262,6 +249,8 @@ func (e *equalityExpr) markExprExpr() {} func (e *equalityExpr) line() int { return e.ln } +func (e *equalityExpr) cerType() cerType { return e.lhs.cerType() } + type equalityRhs struct { op equalityOp value *comparisonExpr @@ -279,6 +268,8 @@ func (c *comparisonExpr) markExprExpr() {} func (c *comparisonExpr) line() int { return c.ln } +func (c *comparisonExpr) cerType() cerType { return c.lhs.cerType() } + type comparisonRhs struct { op comparisonOp value *termExpr @@ -296,6 +287,8 @@ func (t *termExpr) markExprExpr() {} func (t *termExpr) line() int { return t.ln } +func (t *termExpr) cerType() cerType { return t.lhs.cerType() } + type termRhs struct { op shiftOp value *numeralExpr @@ -313,6 +306,8 @@ func (n *numeralExpr) markExprExpr() {} func (n *numeralExpr) line() int { return n.ln } +func (n *numeralExpr) cerType() cerType { return n.lhs.cerType() } + type numeralRhs struct { op addSubOp value *factorExpr @@ -330,6 +325,8 @@ func (f *factorExpr) markExprExpr() {} func (f *factorExpr) line() int { return f.ln } +func (f *factorExpr) cerType() cerType { return f.lhs.cerType() } + type factorRhs struct { op mulDivOp value *unaryExpr @@ -347,6 +344,8 @@ func (u *unaryExpr) markExprExpr() {} func (u *unaryExpr) line() int { return u.ln } +func (u *unaryExpr) cerType() cerType { return u.value.cerType() } + type primaryExpr interface { exprExpr markPrimaryExpr() @@ -372,6 +371,8 @@ func (s *stringExpr) markLiteralExpr() {} func (s *stringExpr) line() int { return s.ln } +func (s *stringExpr) cerType() cerType { return nil } // TODO: string type + type numberExpr struct { typ string s string @@ -388,6 +389,8 @@ func (n *numberExpr) markLiteralExpr() {} func (n *numberExpr) line() int { return n.ln } +func (n *numberExpr) cerType() cerType { return resolveType(n.typ) } + type groupingExpr struct { inner exprExpr ln int @@ -401,9 +404,12 @@ func (g *groupingExpr) markPrimaryExpr() {} func (g *groupingExpr) line() int { return g.ln } +func (g *groupingExpr) cerType() cerType { return g.inner.cerType() } + type callExpr struct { funcName string args *argument + numArgs int ln int } @@ -415,6 +421,15 @@ func (c *callExpr) markPrimaryExpr() {} func (c *callExpr) line() int { return c.ln } +func (c *callExpr) cerType() cerType { + ok, _ := isDeclared(c.funcName, true) + if !ok { + return nil + } + + return funcs[c.funcName].returnType +} + type argument struct { value exprExpr next *argument @@ -432,3 +447,16 @@ func (v *varExpr) markExprExpr() {} func (v *varExpr) markPrimaryExpr() {} func (v *varExpr) line() int { return v.ln } + +func (v *varExpr) cerType() cerType { + ok, mutable := isDeclared(v.name, false) + if !ok { + return nil + } + + if mutable { + return localMuts[currentFunc][v.name].typ + } + + return localConsts[currentFunc][v.name].typ +} diff --git a/generate.go b/generate.go index a32040a..15319b3 100644 --- a/generate.go +++ b/generate.go @@ -94,17 +94,30 @@ func generateFunction(function *functionExpr, w io.Writer) error { currentFunc = function.name defer func() { currentFunc = "" }() - funcs[currentFunc] = struct{}{} + returnType := resolveType(function.returnType) + if returnType == nil { + return errUndeclared{ + name: function.returnType, + kind: undeclaredType, + line: function.line(), + } + } - localConsts[currentFunc] = map[string]string{} - localMuts[currentFunc] = map[string]struct{}{} + funcs[currentFunc] = &funcInfo{returnType: returnType} + + localConsts[currentFunc] = map[string]*localConst{} + localMuts[currentFunc] = map[string]*localMut{} if function.link != defaultLinkage { fmt.Fprintf(w, "%s ", function.link) } - fmt.Fprintf(w, "function %s $%s", function.returnType, function.name) - fmt.Fprintf(w, "(%s) {\n", function.params) + fmt.Fprintf(w, "function %s $%s", returnType.qbeABIType(), function.name) + fmt.Fprintf(w, "(") + if err := generateParam(function.params, function.line(), w); err != nil { + return err + } + fmt.Fprintf(w, ") {\n") fmt.Fprintln(w, "@start") if err := generateBlock(function.blk, w); err != nil { return err @@ -114,12 +127,70 @@ func generateFunction(function *functionExpr, w io.Writer) error { return nil } +func generateParam(p *paramExpr, line int, w io.Writer) error { + if p == nil { + return nil + } + + typ := resolveType(p.typ) + if typ == nil { + return errUndeclared{name: p.typ, kind: undeclaredType, line: line} + } + + funcs[currentFunc].params = append(funcs[currentFunc].params, paramInfo{ + typ: typ, + }) + + fmt.Fprintf(w, "%s %%%s", typ.qbeABIType(), p.name) + if p.next != nil { + fmt.Fprintf(w, ", ") + if err := generateParam(p.next, line, w); err != nil { + return err + } + } + + return nil +} + func generateExternFunc(e *externFuncExpr, w io.Writer) error { if ok, _ := isDeclared(e.name, true); ok { return errAlreadyDeclared{name: e.name, line: e.line()} } - funcs[e.name] = struct{}{} + currentFunc = e.name + defer func() { currentFunc = "" }() + + returnType := resolveType(e.returnType) + + funcs[e.name] = &funcInfo{returnType: returnType} + + if err := generateSignature(e.params, e.line(), w); err != nil { + return err + } + + return nil +} + +func generateSignature(s *signatureExpr, line int, w io.Writer) error { + if s == nil { + return nil + } + + typ := resolveType(s.typ) + if typ == nil { + return errUndeclared{name: s.typ, kind: undeclaredType, line: line} + } + + funcs[currentFunc].params = append(funcs[currentFunc].params, paramInfo{ + typ: typ, + }) + + if s.next != nil { + if err := generateSignature(s.next, line, w); err != nil { + return err + } + } + return nil } @@ -159,6 +230,16 @@ func generateStatement(stmt statementExpr, w io.Writer) error { } func generateReturnStmt(stmt *returnStmt, w io.Writer) error { + returnType := funcs[currentFunc].returnType + valueType := stmt.value.cerType() + if valueType != returnType { + return errTypeMismatch{ + expected: returnType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -179,9 +260,12 @@ func generateConstStmt(stmt *constStmt, toplevel bool, w io.Writer) error { return err } - localConsts[currentFunc][stmt.name] = value + typ := stmt.initial.cerType() + localConsts[currentFunc][stmt.name] = &localConst{ + typ: typ, + } - fmt.Fprintf(w, "%%%s =w add %s, 0\n", stmt.name, value) + fmt.Fprintf(w, "%%%s =%s add %s, 0\n", stmt.name, typ.qbeABIType(), value) return nil } @@ -195,7 +279,10 @@ func generateMutStmt(stmt *mutStmt, toplevel bool, w io.Writer) error { return err } - localMuts[currentFunc][stmt.name] = struct{}{} + typ := stmt.initial.cerType() + localMuts[currentFunc][stmt.name] = &localMut{ + typ: typ, + } fmt.Fprintf(w, "%%%s =l alloc4 4\n", stmt.name) fmt.Fprintf(w, "storew %s, %%%s\n", value, stmt.name) @@ -211,6 +298,16 @@ func generateAssignStmt(stmt *assignStmt, w io.Writer) error { return errImmutable{name: stmt.name, line: stmt.line()} } + varType := localMuts[currentFunc][stmt.name].typ + valueType := stmt.value.cerType() + if varType != valueType { + return errTypeMismatch{ + expected: varType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -229,6 +326,16 @@ func generateAddAssignStmt(stmt *addAssignStmt, w io.Writer) error { return errImmutable{name: stmt.name, line: stmt.line()} } + varType := localMuts[currentFunc][stmt.name].typ + valueType := stmt.value.cerType() + if varType != valueType { + return errTypeMismatch{ + expected: varType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -236,9 +343,13 @@ func generateAddAssignStmt(stmt *addAssignStmt, w io.Writer) error { 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) + typ := varType.qbeBaseType() + loadType := varType.qbeABIType() + storeType := varType.qbeExtType() + + fmt.Fprintf(w, "%s =%s load%s %%%s\n", in, typ, loadType, stmt.name) + fmt.Fprintf(w, "%s =%s add %s, %s\n", out, typ, in, value) + fmt.Fprintf(w, "store%s %s, %%%s\n", storeType, out, stmt.name) return nil } @@ -251,6 +362,16 @@ func generateSubAssignStmt(stmt *subAssignStmt, w io.Writer) error { return errImmutable{name: stmt.name, line: stmt.line()} } + varType := localMuts[currentFunc][stmt.name].typ + valueType := stmt.value.cerType() + if varType != valueType { + return errTypeMismatch{ + expected: varType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -258,9 +379,13 @@ func generateSubAssignStmt(stmt *subAssignStmt, w io.Writer) error { 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) + typ := varType.qbeBaseType() + loadType := varType.qbeABIType() + storeType := varType.qbeExtType() + + fmt.Fprintf(w, "%s =%s load%s %%%s\n", in, typ, loadType, stmt.name) + fmt.Fprintf(w, "%s =%s sub %s, %s\n", out, typ, in, value) + fmt.Fprintf(w, "store%s %s, %%%s\n", storeType, out, stmt.name) return nil } @@ -273,6 +398,16 @@ func generateMulAssignStmt(stmt *mulAssignStmt, w io.Writer) error { return errImmutable{name: stmt.name, line: stmt.line()} } + varType := localMuts[currentFunc][stmt.name].typ + valueType := stmt.value.cerType() + if varType != valueType { + return errTypeMismatch{ + expected: varType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -280,9 +415,13 @@ func generateMulAssignStmt(stmt *mulAssignStmt, w io.Writer) error { 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) + typ := varType.qbeBaseType() + loadType := varType.qbeABIType() + storeType := varType.qbeExtType() + + fmt.Fprintf(w, "%s =%s load%s %%%s\n", in, typ, loadType, stmt.name) + fmt.Fprintf(w, "%s =%s mul %s, %s\n", out, typ, in, value) + fmt.Fprintf(w, "store%s %s, %%%s\n", storeType, out, stmt.name) return nil } @@ -295,6 +434,16 @@ func generateDivAssignStmt(stmt *divAssignStmt, w io.Writer) error { return errImmutable{name: stmt.name, line: stmt.line()} } + varType := localMuts[currentFunc][stmt.name].typ + valueType := stmt.value.cerType() + if varType != valueType { + return errTypeMismatch{ + expected: varType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -302,9 +451,13 @@ func generateDivAssignStmt(stmt *divAssignStmt, w io.Writer) error { 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) + typ := varType.qbeBaseType() + loadType := varType.qbeABIType() + storeType := varType.qbeExtType() + + fmt.Fprintf(w, "%s =%s load%s %%%s\n", in, typ, loadType, stmt.name) + fmt.Fprintf(w, "%s =%s div %s, %s\n", out, typ, in, value) + fmt.Fprintf(w, "store%s %s, %%%s\n", storeType, out, stmt.name) return nil } @@ -317,6 +470,16 @@ func generateRemAssignStmt(stmt *remAssignStmt, w io.Writer) error { return errImmutable{name: stmt.name, line: stmt.line()} } + varType := localMuts[currentFunc][stmt.name].typ + valueType := stmt.value.cerType() + if varType != valueType { + return errTypeMismatch{ + expected: varType, + got: valueType, + line: stmt.line(), + } + } + value, err := stmt.value.generate(w) if err != nil { return err @@ -324,9 +487,13 @@ func generateRemAssignStmt(stmt *remAssignStmt, w io.Writer) error { in, out := allocReg(), allocReg() - fmt.Fprintf(w, "%s =w loadl %%%s\n", in, stmt.name) - fmt.Fprintf(w, "%s =w rem %s, %s\n", out, in, value) - fmt.Fprintf(w, "storew %s, %%%s\n", out, stmt.name) + typ := varType.qbeBaseType() + loadType := varType.qbeABIType() + + storeType := varType.qbeExtType() + fmt.Fprintf(w, "%s =%s load%s %%%s\n", in, typ, loadType, stmt.name) + fmt.Fprintf(w, "%s =%s rem %s, %s\n", out, typ, in, value) + fmt.Fprintf(w, "store%s %s, %%%s\n", storeType, out, stmt.name) return nil } @@ -338,6 +505,16 @@ func (e *equalityExpr) generate(w io.Writer) (string, error) { out := lhs for _, rhs := range e.rhs { + lhsType := e.lhs.cerType() + rhsType := rhs.value.cerType() + if rhsType != lhsType { + return "", errTypeMismatch{ + expected: lhsType, + got: rhsType, + line: e.line(), + } + } + out, err = rhs.generate(out, w) if err != nil { return "", err @@ -378,6 +555,16 @@ func (c *comparisonExpr) generate(w io.Writer) (string, error) { out := lhs if c.rhs != nil { + lhsType := c.lhs.cerType() + rhsType := c.rhs.value.cerType() + if rhsType != lhsType { + return "", errTypeMismatch{ + expected: lhsType, + got: rhsType, + line: c.line(), + } + } + out, err = c.rhs.generate(out, w) if err != nil { return "", err @@ -422,6 +609,16 @@ func (t *termExpr) generate(w io.Writer) (string, error) { out := lhs for _, rhs := range t.rhs { + lhsType := t.lhs.cerType() + rhsType := rhs.value.cerType() + if rhsType != lhsType { + return "", errTypeMismatch{ + expected: lhsType, + got: rhsType, + line: t.line(), + } + } + out, err = rhs.generate(out, w) if err != nil { return "", err @@ -460,6 +657,16 @@ func (n *numeralExpr) generate(w io.Writer) (string, error) { out := lhs for _, rhs := range n.rhs { + lhsType := n.lhs.cerType() + rhsType := rhs.value.cerType() + if rhsType != lhsType { + return "", errTypeMismatch{ + expected: lhsType, + got: rhsType, + line: n.line(), + } + } + out, err = rhs.generate(out, w) if err != nil { return "", err @@ -498,6 +705,16 @@ func (f *factorExpr) generate(w io.Writer) (string, error) { out := lhs for _, rhs := range f.rhs { + lhsType := f.lhs.cerType() + rhsType := rhs.value.cerType() + if rhsType != lhsType { + return "", errTypeMismatch{ + expected: lhsType, + got: rhsType, + line: f.line(), + } + } + out, err = rhs.generate(out, w) if err != nil { return "", err @@ -570,6 +787,15 @@ func (s *stringExpr) generate(w io.Writer) (string, error) { } func (n *numberExpr) generate(w io.Writer) (string, error) { + typ := resolveType(n.typ) + if typ == nil { + return "", errUndeclared{ + name: n.typ, + kind: undeclaredType, + line: n.line(), + } + } + base := 10 switch { case strings.HasPrefix(n.s, "0x"): @@ -597,27 +823,53 @@ func (c *callExpr) generate(w io.Writer) (string, error) { _, ok := funcs[c.funcName] if !ok { return "", errUndeclared{ - name: c.funcName, - isFunc: true, - line: c.line(), + name: c.funcName, + kind: undeclaredFunction, + line: c.line(), } } + returnType := funcs[c.funcName].returnType + ret := allocReg() - fmt.Fprintf(w, "%s =w call $%s(", ret, c.funcName) + if c.numArgs != len(funcs[c.funcName].params) { + return "", errArgNumMismatch{ + expected: len(funcs[c.funcName].params), + got: c.numArgs, + line: c.line(), + } + } + args := make([]string, 0) delim := "" + i := 0 for arg := c.args; arg != nil; arg = arg.next { reg, err := arg.value.generate(w) if err != nil { return "", err } - fmt.Fprintf(w, "w %s%s", reg, delim) + typ := arg.value.cerType() + neededType := funcs[c.funcName].params[i].typ + if typ != neededType { + return "", errTypeMismatch{ + expected: neededType, + got: typ, + line: c.line(), + } + } + + s := fmt.Sprintf("%s %s%s", typ.qbeABIType(), reg, delim) + args = append(args, s) delim = "," + i++ } + fmt.Fprintf(w, "%s =%s call $%s(", ret, returnType.qbeABIType(), c.funcName) + for _, arg := range args { + fmt.Fprintf(w, "%s", arg) + } fmt.Fprintf(w, ")\n") return ret, nil @@ -635,5 +887,5 @@ func (v *varExpr) generate(w io.Writer) (string, error) { return reg, nil } - return localConsts[currentFunc][v.name], nil + return "%" + v.name, nil } diff --git a/generate_error.go b/generate_error.go index e89add2..88fe3f4 100644 --- a/generate_error.go +++ b/generate_error.go @@ -15,19 +15,35 @@ func (e errAlreadyDeclared) Error() string { return fmt.Sprintf("%d: redeclaration of %q\n", e.line, e.name) } +type undeclaredKind int + +const ( + undeclaredVariable undeclaredKind = iota + undeclaredFunction + undeclaredType +) + +func (u undeclaredKind) String() string { + switch u { + case undeclaredVariable: + return "variable" + case undeclaredFunction: + return "function" + case undeclaredType: + return "type" + default: + return "identifier" + } +} + type errUndeclared struct { - name string - isFunc bool - line int + name string + kind undeclaredKind + line int } func (e errUndeclared) Error() string { - kind := "variable" - if e.isFunc { - kind = "function" - } - - return fmt.Sprintf("%d: undeclared %s %q\n", e.line, kind, e.name) + return fmt.Sprintf("%d: undeclared %s %q\n", e.line, e.kind, e.name) } type errImmutable struct { @@ -38,3 +54,21 @@ type errImmutable struct { func (e errImmutable) Error() string { return fmt.Sprintf("%d: cannot assign to constant %q\n", e.line, e.name) } + +type errTypeMismatch struct { + expected, got cerType + line int +} + +func (e errTypeMismatch) Error() string { + return fmt.Sprintf("%d: expected type %s, got %s", e.line, e.expected, e.got) +} + +type errArgNumMismatch struct { + expected, got int + line int +} + +func (e errArgNumMismatch) Error() string { + return fmt.Sprintf("%d: function expects %d arguments, got %d", e.line, e.expected, e.got) +} @@ -1267,7 +1267,8 @@ func parseCall(toks *tokens) (*callExpr, error) { return nil, nil } - args, err := parseArg(toks) + numArgs := 0 + args, err := parseArg(toks, &numArgs) if err != nil { return nil, err } @@ -1276,10 +1277,15 @@ func parseCall(toks *tokens) (*callExpr, error) { return nil, err } - return &callExpr{funcName: nameTok.value, args: args, ln: nameTok.line}, nil + return &callExpr{ + funcName: nameTok.value, + args: args, + numArgs: numArgs, + ln: nameTok.line, + }, nil } -func parseArg(toks *tokens) (*argument, error) { +func parseArg(toks *tokens, numTotal *int) (*argument, error) { ok, err := toks.match(rparen) if err != nil { return nil, err @@ -1300,14 +1306,16 @@ func parseArg(toks *tokens) (*argument, error) { } if !ok { toks.unreadToken() + *numTotal++ return &argument{value: arg}, nil } - next, err := parseArg(toks) + next, err := parseArg(toks, numTotal) if err != nil { return nil, err } + *numTotal++ return &argument{value: arg, next: next}, nil } @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: 2024 Himbeer <himbeer@disroot.org> +// +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import "fmt" + +type cerType interface { + fmt.Stringer + qbeBaseType() string + qbeExtType() string + qbeABIType() string +} + +type cerInteger struct { + bits int + unsigned bool +} + +func (c cerInteger) String() string { + unsigned := "" + if c.unsigned { + unsigned = "u" + } + + return fmt.Sprintf("%sint%d", unsigned, c.bits) +} + +func (c cerInteger) qbeBaseType() string { + switch { + case c.bits > 32: + return "l" + default: + return "w" + } +} + +func (c cerInteger) qbeExtType() string { + switch { + case c.bits > 32: + return "l" + case c.bits > 16: + return "w" + case c.bits > 8: + return "h" + default: + return "b" + } +} + +func (c cerInteger) qbeABIType() string { + signedness := "s" + if c.unsigned { + signedness = "u" + } + + switch { + case c.bits > 32: + return "l" + case c.bits > 16: + return "w" + case c.bits > 8: + return signedness + "h" + default: + return signedness + "b" + } +} + +func resolveType(name string) cerType { + switch name { + case "int8": + return cerInteger{bits: 8} + case "uint8": + return cerInteger{bits: 8, unsigned: true} + case "int16": + return cerInteger{bits: 16} + case "uint16": + return cerInteger{bits: 16, unsigned: true} + case "int32": + return cerInteger{bits: 32} + case "uint32": + return cerInteger{bits: 32, unsigned: true} + case "int64": + return cerInteger{bits: 64} + case "uint64": + return cerInteger{bits: 64, unsigned: true} + default: + return nil + } +} + +var ( + cerInt8 = cerInteger{bits: 8} + cerUint8 = cerInteger{bits: 8, unsigned: true} + cerInt16 = cerInteger{bits: 16} + cerUint16 = cerInteger{bits: 16, unsigned: true} + cerInt32 = cerInteger{bits: 32} + cerUint32 = cerInteger{bits: 32, unsigned: true} + cerInt64 = cerInteger{bits: 64} + cerUint64 = cerInteger{bits: 64, unsigned: true} +) |