node: support const and class const

This commit is contained in:
mappu 2020-04-08 20:24:36 +12:00
parent 9b5b72392f
commit 142e26bbfe
1 changed files with 44 additions and 0 deletions

44
node.go
View File

@ -201,6 +201,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
className := n.ClassName.(*node.Identifier).Value
this.currentClassName = className
memberVars := []string{}
memberConsts := []string{}
memberFuncs := []string{}
if n.Extends != nil {
@ -240,6 +241,30 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
memberVars = append(memberVars, name+" "+memberType)
case *stmt.ClassConstList:
// Class constant
// Go doesn't have class constants - convert it to just a package const, prefixed with the const name
// TODO detect, intercept and re-reroute any future references to these consts!
// That might need a separate compiler pass
for _, c_ := range s.Consts {
c, ok := c_.(*stmt.Constant)
if !ok {
return "", parseErr{c_, fmt.Errorf("expected stmt.Constant")}
}
name, err := applyVisibilityModifier(c.ConstantName.(*node.Identifier).Value, s.Modifiers)
if err != nil {
return "", parseErr{c_, err}
}
constExpr, err := this.convert(c.Expr)
if err != nil {
return "", parseErr{c.Expr, err}
}
memberConsts = append(memberConsts, className+name+" = "+constExpr)
}
case *stmt.ClassMethod:
// Function name
// If function is public/private/protected, set the first character to upper/lowercase
@ -302,6 +327,13 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
}
}
// Write out any class constants
if len(memberConsts) == 1 {
ret += "const " + memberConsts[0] + "\n"
} else if len(memberConsts) > 1 {
ret += "const (\n" + strings.Join(memberConsts, "\n") + ")\n"
}
// Create struct typedef containing all explicit properties
ret += "type " + className + " struct {\n"
ret += "\t" + strings.Join(memberVars, "\n\t") + "\n"
@ -876,6 +908,18 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
return this.convert(expr.NewFunctionCall(transparentNameNode, n.ArgumentList))
case *expr.ClassConstFetch:
// We converted class constants to package-level constants
className, err := this.resolveName(n.Class)
if err != nil {
return "", parseErr{n, err}
}
constName := n.ConstantName.(*node.Identifier).Value
// TODO fix up visibility modifier
return className + constName, nil
case *expr.Exit:
// die(0) - set process exit code and exit
// die("message") - print to stdout and exit 0