diff options
Diffstat (limited to 'nexgb/xgbgen/xml_expression.go')
-rw-r--r-- | nexgb/xgbgen/xml_expression.go | 160 |
1 files changed, 0 insertions, 160 deletions
diff --git a/nexgb/xgbgen/xml_expression.go b/nexgb/xgbgen/xml_expression.go deleted file mode 100644 index 2989668..0000000 --- a/nexgb/xgbgen/xml_expression.go +++ /dev/null @@ -1,160 +0,0 @@ -package main - -import ( - "encoding/xml" - "fmt" - "log" - "strconv" -) - -type XMLExpression struct { - XMLName xml.Name - - Exprs []*XMLExpression `xml:",any"` - - Data string `xml:",chardata"` - Op string `xml:"op,attr"` - Ref string `xml:"ref,attr"` -} - -func newValueExpression(v uint) *XMLExpression { - return &XMLExpression{ - XMLName: xml.Name{Local: "value"}, - Data: fmt.Sprintf("%d", v), - } -} - -// String is for debugging. For actual use, please use 'Morph'. -func (e *XMLExpression) String() string { - switch e.XMLName.Local { - case "op": - return fmt.Sprintf("(%s %s %s)", e.Exprs[0], e.Op, e.Exprs[1]) - case "unop": - return fmt.Sprintf("(%s (%s))", e.Op, e.Exprs[0]) - case "popcount": - return fmt.Sprintf("popcount(%s)", e.Exprs[0]) - case "fieldref": - fallthrough - case "value": - return fmt.Sprintf("%s", e.Data) - case "bit": - return fmt.Sprintf("(1 << %s)", e.Data) - case "enumref": - return fmt.Sprintf("%s%s", e.Ref, e.Data) - case "sumof": - return fmt.Sprintf("sum(%s)", e.Ref) - default: - log.Panicf("Unrecognized expression element: %s", e.XMLName.Local) - } - - panic("unreachable") -} - -// Eval is used to *attempt* to compute a concrete value for a particular -// expression. This is used in the initial setup to instantiate values for -// empty items in enums. -// We can't compute a concrete value for expressions that rely on a context, -// i.e., some field value. -func (e *XMLExpression) Eval() uint { - switch e.XMLName.Local { - case "op": - if len(e.Exprs) != 2 { - log.Panicf("'op' found %d expressions; expected 2.", len(e.Exprs)) - } - return e.BinaryOp(e.Exprs[0], e.Exprs[1]).Eval() - case "unop": - if len(e.Exprs) != 1 { - log.Panicf("'unop' found %d expressions; expected 1.", len(e.Exprs)) - } - return e.UnaryOp(e.Exprs[0]).Eval() - case "popcount": - if len(e.Exprs) != 1 { - log.Panicf("'popcount' found %d expressions; expected 1.", - len(e.Exprs)) - } - return popCount(e.Exprs[0].Eval()) - case "value": - val, err := strconv.Atoi(e.Data) - if err != nil { - log.Panicf("Could not convert '%s' in 'value' expression to int.", - e.Data) - } - return uint(val) - case "bit": - bit, err := strconv.Atoi(e.Data) - if err != nil { - log.Panicf("Could not convert '%s' in 'bit' expression to int.", - e.Data) - } - if bit < 0 || bit > 31 { - log.Panicf("A 'bit' literal must be in the range [0, 31], but "+ - " is %d", bit) - } - return 1 << uint(bit) - case "fieldref": - log.Panicf("Cannot compute concrete value of 'fieldref' in "+ - "expression '%s'.", e) - case "enumref": - log.Panicf("Cannot compute concrete value of 'enumref' in "+ - "expression '%s'.", e) - case "sumof": - log.Panicf("Cannot compute concrete value of 'sumof' in "+ - "expression '%s'.", e) - } - - log.Panicf("Unrecognized tag '%s' in expression context. Expected one of "+ - "op, fieldref, value, bit, enumref, unop, sumof or popcount.", - e.XMLName.Local) - panic("unreachable") -} - -func (e *XMLExpression) BinaryOp(oprnd1, oprnd2 *XMLExpression) *XMLExpression { - if e.XMLName.Local != "op" { - log.Panicf("Cannot perform binary operation on non-op expression: %s", - e.XMLName.Local) - } - if len(e.Op) == 0 { - log.Panicf("Cannot perform binary operation without operator for: %s", - e.XMLName.Local) - } - - wrap := newValueExpression - switch e.Op { - case "+": - return wrap(oprnd1.Eval() + oprnd2.Eval()) - case "-": - return wrap(oprnd1.Eval() + oprnd2.Eval()) - case "*": - return wrap(oprnd1.Eval() * oprnd2.Eval()) - case "/": - return wrap(oprnd1.Eval() / oprnd2.Eval()) - case "&": - return wrap(oprnd1.Eval() & oprnd2.Eval()) - case "<<": - return wrap(oprnd1.Eval() << oprnd2.Eval()) - } - - log.Panicf("Invalid binary operator '%s' for '%s' expression.", - e.Op, e.XMLName.Local) - panic("unreachable") -} - -func (e *XMLExpression) UnaryOp(oprnd *XMLExpression) *XMLExpression { - if e.XMLName.Local != "unop" { - log.Panicf("Cannot perform unary operation on non-unop expression: %s", - e.XMLName.Local) - } - if len(e.Op) == 0 { - log.Panicf("Cannot perform unary operation without operator for: %s", - e.XMLName.Local) - } - - switch e.Op { - case "~": - return newValueExpression(^oprnd.Eval()) - } - - log.Panicf("Invalid unary operator '%s' for '%s' expression.", - e.Op, e.XMLName.Local) - panic("unreachable") -} |