mirror of
https://gitee.com/wa-lang/wa.git
synced 2025-12-06 17:19:15 +08:00
优化 native/ast 字面值结构体
This commit is contained in:
@@ -34,10 +34,11 @@ type CommentGroup struct {
|
||||
|
||||
// 基本的面值
|
||||
type BasicLit struct {
|
||||
Pos token.Pos // 位置
|
||||
Kind token.Token // INT/FLOAT/CHAR/STRING, 默认类型 INT=>I64, FLOAT=>F64, CHAR => I32
|
||||
TypeCast token.Token // 默认类型强制转型, I32/U32/I64/U64/F32/F64/NONE
|
||||
Value string // 42, 0x7f, 3.14, 1e-9, 'a', '\x7f', "foo" or `\m\n\o`
|
||||
Pos token.Pos // 位置
|
||||
TypeCast token.Token // 默认类型强制转型, I32/U32/I64/U64/F32/F64/NONE
|
||||
LitKind token.Token // INT/FLOAT/CHAR/STRING, 默认类型 INT=>I64, FLOAT=>F64, CHAR => I32
|
||||
LitString string // 原始的字符串: 42, 0x7f, 3.14, 1e-9, 'a', '\x7f', "foo" or `\m\n\o`
|
||||
ConstV interface{} // 解析后的常量值, 对应的类型: int64, float64, string
|
||||
}
|
||||
|
||||
// 全局常量
|
||||
|
||||
@@ -242,111 +242,6 @@ func (p *parser) parseInt32Lit() int32 {
|
||||
return int32(n)
|
||||
}
|
||||
|
||||
func (p *parser) parseUint32Lit() uint32 {
|
||||
pos, lit := p.pos, p.lit
|
||||
|
||||
if p.tok == token.CHAR {
|
||||
p.acceptToken(token.CHAR)
|
||||
return uint32(lit[1]) // '?'
|
||||
}
|
||||
|
||||
p.acceptToken(token.INT)
|
||||
|
||||
if len(lit) > 2 && lit[0] == '0' && (lit[1] == 'x' || lit[1] == 'X') {
|
||||
n, err := strconv.ParseUint(lit[2:], 16, 32)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect int32, got %q", lit)
|
||||
}
|
||||
return uint32(n)
|
||||
}
|
||||
|
||||
// 需要支持 u32 和 -1 两种格式
|
||||
n, err := strconv.ParseUint(lit, 10, 32)
|
||||
if err != nil {
|
||||
if n, errx := strconv.ParseUint(lit, 10, 32); errx == nil {
|
||||
return uint32(n)
|
||||
} else {
|
||||
p.errorf(pos, "expect int32, got %q, err = %v", lit, err)
|
||||
}
|
||||
|
||||
}
|
||||
return uint32(n)
|
||||
}
|
||||
|
||||
func (p *parser) parseInt64Lit() int64 {
|
||||
pos, lit := p.pos, p.lit
|
||||
p.acceptToken(token.INT)
|
||||
|
||||
if len(lit) > 2 && lit[0] == '0' && (lit[1] == 'x' || lit[1] == 'X') {
|
||||
n, err := strconv.ParseInt(lit[2:], 16, 64)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect int64, got %q", lit)
|
||||
}
|
||||
return int64(n)
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(lit, 10, 64)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect int64, got %q", lit)
|
||||
}
|
||||
return int64(uint64(n))
|
||||
}
|
||||
|
||||
func (p *parser) parseUint64Lit() uint64 {
|
||||
pos, lit := p.pos, p.lit
|
||||
p.acceptToken(token.INT)
|
||||
|
||||
if len(lit) > 2 && lit[0] == '0' && (lit[1] == 'x' || lit[1] == 'X') {
|
||||
n, err := strconv.ParseUint(lit[2:], 16, 64)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect int64, got %q", lit)
|
||||
}
|
||||
return uint64(n)
|
||||
}
|
||||
|
||||
n, err := strconv.ParseUint(lit, 10, 64)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect int64, got %q", lit)
|
||||
}
|
||||
return uint64(n)
|
||||
}
|
||||
|
||||
// 解析浮点数常量面值
|
||||
func (p *parser) parseFloat32Lit() float32 {
|
||||
pos, lit := p.pos, p.lit
|
||||
p.acceptToken(token.FLOAT, token.INT)
|
||||
|
||||
n, err := strconv.ParseFloat(lit, 32)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect float32, got %q", lit)
|
||||
}
|
||||
return float32(n)
|
||||
}
|
||||
func (p *parser) parseFloat64Lit() float64 {
|
||||
pos, lit := p.pos, p.lit
|
||||
p.acceptToken(token.FLOAT, token.INT)
|
||||
|
||||
n, err := strconv.ParseFloat(lit, 64)
|
||||
if err != nil {
|
||||
p.errorf(pos, "expect float64, got %q", lit)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// 解析字符常量面值(含二进制数据)
|
||||
func (p *parser) parseCharLit() string {
|
||||
s := p.lit
|
||||
p.acceptToken(token.CHAR)
|
||||
return s
|
||||
}
|
||||
|
||||
// 解析字符串常量面值(含二进制数据)
|
||||
func (p *parser) parseStringLit() string {
|
||||
s := p.lit
|
||||
p.acceptToken(token.STRING)
|
||||
return s
|
||||
}
|
||||
|
||||
// 解析寄存器
|
||||
func (p *parser) parseRegister() abi.RegType {
|
||||
if !p.tok.IsRegister() {
|
||||
|
||||
87
internal/native/parser/parser_basic_lit.go
Normal file
87
internal/native/parser/parser_basic_lit.go
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2025 武汉凹语言科技有限公司
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
"wa-lang.org/wa/internal/native/ast"
|
||||
"wa-lang.org/wa/internal/native/token"
|
||||
)
|
||||
|
||||
// 解析值
|
||||
func (p *parser) parseBasicLit() *ast.BasicLit {
|
||||
pVal := &ast.BasicLit{Pos: p.pos}
|
||||
|
||||
// 带类型的常量
|
||||
// const $D = i64('D') # i64
|
||||
// 常量 $甲 = 整64(‘A’) # i64
|
||||
|
||||
switch p.tok {
|
||||
case token.I32, token.I32_zh,
|
||||
token.I64, token.I64_zh,
|
||||
token.U32, token.U32_zh,
|
||||
token.U64, token.U64_zh,
|
||||
token.F32, token.F32_zh,
|
||||
token.F64, token.F64_zh,
|
||||
token.PTR, token.PTR_zh:
|
||||
pVal.TypeCast = p.tok
|
||||
p.acceptToken(token.LPAREN)
|
||||
defer p.acceptToken(token.RPAREN)
|
||||
}
|
||||
|
||||
// 默认类型
|
||||
switch p.tok {
|
||||
case token.CHAR, token.INT, token.FLOAT:
|
||||
pVal.LitKind = p.tok
|
||||
if pVal.TypeCast == token.NONE {
|
||||
pVal.TypeCast = p.tok.DefaultNumberType()
|
||||
}
|
||||
pVal.LitString = p.lit
|
||||
return pVal
|
||||
case token.STRING:
|
||||
pVal.LitKind = p.tok
|
||||
pVal.LitString = p.lit
|
||||
return pVal
|
||||
default:
|
||||
p.errorf(p.pos, "expect type or lit, got %v", p.tok)
|
||||
}
|
||||
|
||||
// 解析常量的值
|
||||
switch pVal.LitKind {
|
||||
case token.INT:
|
||||
if x, err := strconv.ParseInt(pVal.LitString, 0, 64); err == nil {
|
||||
pVal.ConstV = int64(x)
|
||||
}
|
||||
case token.FLOAT:
|
||||
if f, ok := new(big.Float).SetString(pVal.LitString); ok {
|
||||
if f64V, acc := f.Float64(); acc != big.Exact {
|
||||
pVal.ConstV = float64(f64V)
|
||||
} else {
|
||||
p.errorf(pVal.Pos, "float %v %v", pVal.LitString, acc)
|
||||
}
|
||||
} else {
|
||||
p.errorf(pVal.Pos, "expect float, got %v", pVal.LitString)
|
||||
}
|
||||
|
||||
case token.CHAR:
|
||||
if n := len(pVal.LitString); n >= 2 {
|
||||
if code, _, _, err := strconv.UnquoteChar(pVal.LitString[1:n-1], '\''); err == nil {
|
||||
pVal.ConstV = int64(code)
|
||||
}
|
||||
}
|
||||
|
||||
case token.STRING:
|
||||
if s, err := strconv.Unquote(pVal.LitString); err == nil {
|
||||
pVal.ConstV = s
|
||||
}
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("%v is not a valid token", pVal.LitKind))
|
||||
}
|
||||
|
||||
return pVal
|
||||
}
|
||||
@@ -20,7 +20,7 @@ func (p *parser) parseConst() *ast.Const {
|
||||
p.acceptTokenAorB(token.CONST, token.CONST_zh)
|
||||
pConst.Name = p.parseIdent()
|
||||
p.acceptToken(token.ASSIGN)
|
||||
pConst.Value = p.parseLitValue()
|
||||
pConst.Value = p.parseBasicLit()
|
||||
pConst.Comment = p.parseTailComment(pConst.Pos)
|
||||
|
||||
p.consumeSemicolonList()
|
||||
|
||||
@@ -77,7 +77,7 @@ func (p *parser) parseGlobal() *ast.Global {
|
||||
if p.tok == token.IDENT {
|
||||
initV.Symbal = p.parseIdent()
|
||||
} else {
|
||||
initV.Lit = p.parseLitValue()
|
||||
initV.Lit = p.parseBasicLit()
|
||||
}
|
||||
initV.Comment = p.parseTailComment(initV.Pos)
|
||||
g.Init = []ast.InitValue{initV}
|
||||
@@ -109,7 +109,7 @@ Loop:
|
||||
if p.tok == token.IDENT {
|
||||
initV.Symbal = p.parseIdent()
|
||||
} else {
|
||||
initV.Lit = p.parseLitValue()
|
||||
initV.Lit = p.parseBasicLit()
|
||||
}
|
||||
initV.Comment = p.parseTailComment(initV.Pos)
|
||||
g.Init = append(g.Init, initV)
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright (C) 2025 武汉凹语言科技有限公司
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
package parser
|
||||
|
||||
import (
|
||||
"wa-lang.org/wa/internal/native/ast"
|
||||
"wa-lang.org/wa/internal/native/token"
|
||||
)
|
||||
|
||||
// 解析值
|
||||
func (p *parser) parseLitValue() *ast.BasicLit {
|
||||
pVal := &ast.BasicLit{Pos: p.pos}
|
||||
|
||||
// 带类型的常量
|
||||
// const $D = i64('D') # i64
|
||||
// 常量 $甲 = 整64(‘A’) # i64
|
||||
|
||||
switch p.tok {
|
||||
case token.I32, token.I32_zh,
|
||||
token.I64, token.I64_zh,
|
||||
token.U32, token.U32_zh,
|
||||
token.U64, token.U64_zh,
|
||||
token.F32, token.F32_zh,
|
||||
token.F64, token.F64_zh,
|
||||
token.PTR, token.PTR_zh:
|
||||
pVal.TypeCast = p.tok
|
||||
p.acceptToken(token.LPAREN)
|
||||
defer p.acceptToken(token.RPAREN)
|
||||
}
|
||||
|
||||
// 默认类型
|
||||
switch p.tok {
|
||||
case token.CHAR, token.INT, token.FLOAT:
|
||||
pVal.Kind = p.tok
|
||||
if pVal.TypeCast == token.NONE {
|
||||
pVal.TypeCast = p.tok.DefaultNumberType()
|
||||
}
|
||||
pVal.Value = p.lit
|
||||
return pVal
|
||||
case token.STRING:
|
||||
pVal.Kind = p.tok
|
||||
pVal.Value = p.lit
|
||||
return pVal
|
||||
default:
|
||||
p.errorf(p.pos, "expect type or lit, got %v", p.tok)
|
||||
}
|
||||
|
||||
return pVal
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
func (p *wsPrinter) printConsts() error {
|
||||
for _, x := range p.f.Consts {
|
||||
fmt.Fprintf(p.w, "const %s = %v\n", x.Name, x.Value.Value)
|
||||
fmt.Fprintf(p.w, "const %s = %v\n", x.Name, x.Value.LitString)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ func (p *wsPrinter) printGlobals() error {
|
||||
case len(g.Init) == 1 && g.Init[0].Offset == 0:
|
||||
xInit := g.Init[0]
|
||||
if xInit.Lit != nil {
|
||||
if xInit.Lit.Kind.DefaultNumberType() != xInit.Lit.TypeCast {
|
||||
fmt.Fprintf(p.w, "global %s:%d = %v(%s)\n", g.Name, g.Size, xInit.Lit.TypeCast, xInit.Lit.Value)
|
||||
if xInit.Lit.LitKind.DefaultNumberType() != xInit.Lit.TypeCast {
|
||||
fmt.Fprintf(p.w, "global %s:%d = %v(%s)\n", g.Name, g.Size, xInit.Lit.TypeCast, xInit.Lit.LitString)
|
||||
} else {
|
||||
fmt.Fprintf(p.w, "global %s:%d = %s\n", g.Name, g.Size, xInit.Lit.Value)
|
||||
fmt.Fprintf(p.w, "global %s:%d = %s\n", g.Name, g.Size, xInit.Lit.LitString)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(p.w, "global %s:%d = %s\n", g.Name, g.Size, xInit.Symbal)
|
||||
@@ -37,10 +37,10 @@ func (p *wsPrinter) printGlobals() error {
|
||||
fmt.Fprintf(p.w, "global %s:%d = {\n", g.Name, g.Size)
|
||||
for _, xInit := range g.Init {
|
||||
if xInit.Lit != nil {
|
||||
if xInit.Lit.Kind.DefaultNumberType() != xInit.Lit.TypeCast {
|
||||
fmt.Fprintf(p.w, "\t%d: %v(%s),\n", xInit.Offset, xInit.Lit.TypeCast, xInit.Lit.Value)
|
||||
if xInit.Lit.LitKind.DefaultNumberType() != xInit.Lit.TypeCast {
|
||||
fmt.Fprintf(p.w, "\t%d: %v(%s),\n", xInit.Offset, xInit.Lit.TypeCast, xInit.Lit.LitString)
|
||||
} else {
|
||||
fmt.Fprintf(p.w, "\t%d: %s,\n", xInit.Offset, xInit.Lit.Value)
|
||||
fmt.Fprintf(p.w, "\t%d: %s,\n", xInit.Offset, xInit.Lit.LitString)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(p.w, "\t%d: %s,\n", xInit.Offset, xInit.Symbal)
|
||||
|
||||
Reference in New Issue
Block a user