parser 增加泛型宏参数解析; 类型定义必须 : 分隔

This commit is contained in:
chai2010
2024-01-13 00:44:45 +08:00
parent 7ed7e83935
commit 292168f995
21 changed files with 98 additions and 57 deletions

View File

@@ -847,7 +847,7 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [
colonPos = p.pos
p.next()
} else {
if p.tok != token.RPAREN {
if p.tok != token.RPAREN && p.tok != token.RBRACK {
p.expect(token.COLON)
}
}
@@ -941,6 +941,33 @@ func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList {
return nil
}
func (p *parser) parseTypeParams(scope *ast.Scope) (tparams *ast.FieldList) {
if p.trace {
defer un(trace(p, "TypeParams"))
}
// 数组和切片歧义, 必须加 ':' 分隔
// type byteReplacer :[256]byte
// type byteReplacer :[]byte
if p.tok != token.LBRACK {
return nil
}
lparen := p.expect(token.LBRACK)
if p.tok == token.RBRACK {
p.next()
return nil
}
params := p.parseParameterList(scope, false)
rparen := p.expect(token.RBRACK)
tparams = &ast.FieldList{Opening: lparen, List: params, Closing: rparen}
return
}
func (p *parser) parseSignature(scope *ast.Scope) (params, results *ast.FieldList, arrowPos token.Pos) {
if p.trace {
defer un(trace(p, "Signature"))
@@ -986,13 +1013,16 @@ func (p *parser) parseFuncType() (*ast.FuncType, *ast.Scope) {
pos := p.expect(token.FUNC)
scope := ast.NewScope(p.topScope) // function scope
tparams := p.parseTypeParams(scope)
params, results, arrowPos := p.parseSignature(scope)
return &ast.FuncType{
Func: pos,
Params: params,
ArrowPos: arrowPos,
Results: results,
Func: pos,
TypeParams: tparams,
Params: params,
ArrowPos: arrowPos,
Results: results,
}, scope
}
@@ -2439,12 +2469,20 @@ func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.
// containing block.
// (Global identifiers are resolved in a separate phase after parsing.)
spec := &ast.TypeSpec{Doc: doc, Name: ident}
spec.TypeParams = p.parseTypeParams(p.topScope)
p.declare(spec, nil, p.topScope, ast.Typ, ident)
if p.tok == token.COLON {
spec.ColonPos = p.pos
p.next()
}
spec.Type = p.parseType()
if _, ok := spec.Type.(*ast.StructType); !ok {
if spec.TypeParams != nil {
p.error(spec.TypeParams.Opening, "type params only support struct type")
}
}
p.expectSemi() // call before accessing p.linecomment
spec.Comment = p.lineComment
@@ -2523,6 +2561,7 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
}
}
tparams := p.parseTypeParams(scope)
params, results, arrowPos := p.parseSignature(scope)
var body *ast.BlockStmt
@@ -2536,10 +2575,11 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
Recv: recv,
Name: ident,
Type: &ast.FuncType{
Func: pos,
Params: params,
ArrowPos: arrowPos,
Results: results,
Func: pos,
TypeParams: tparams,
Params: params,
ArrowPos: arrowPos,
Results: results,
},
Body: body,
}

View File

@@ -1571,6 +1571,7 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
} else {
p.print(vtab)
}
p.print(token.COLON)
p.expr(s.Type)
p.setComment(s.Comment)

View File

@@ -7,7 +7,7 @@ func main {
vm.Run()
}
type BrainFuck struct {
type BrainFuck :struct {
mem: [30000]byte
code: string
pos: int

View File

@@ -1,7 +1,7 @@
// 版权 @2022 凹语言 作者。保留所有权利。
// BF 虚拟机
type BrainFuck struct {
type BrainFuck :struct {
mem: [30000]byte
code: string
pos: int

View File

@@ -1,6 +1,6 @@
// 版权 @2021 凹语言 作者。保留所有权利。
type T1 struct {
type T1 :struct {
a: i32
b: string
}
@@ -9,11 +9,11 @@ func T1.print {
println("a: ", this.a)
}
type I interface {
type I :interface {
print()
}
type T2 struct {
type T2 :struct {
a: []i32
}

View File

@@ -6,7 +6,7 @@
import "strconv" => __yystrconv__
type exprSymType struct {
type exprSymType :struct {
yys: int
num: int
}
@@ -35,12 +35,12 @@ const exprInitialStackSize = 16
// Lex 结束标志
const eof = 0
type exprToken struct {
type exprToken :struct {
Kind: int
Value: int
}
type exprLexer struct {
type exprLexer :struct {
tokens: []exprToken
pos: int
}
@@ -143,7 +143,7 @@ global exprTok3 = [...]int{
0,
}
type exprErrorMessageInfo struct {
type exprErrorMessageInfo :struct {
state: int
token: int
msg: string
@@ -158,7 +158,7 @@ global (
exprErrorVerbose = false
)
type exprParser struct {
type exprParser :struct {
lval: exprSymType
stack: [exprInitialStackSize]exprSymType
char: int

View File

@@ -1,18 +1,18 @@
// 版权 @2021 凹语言 作者。保留所有权利。
type T1 struct {
type T1 :struct {
a: i32
}
type T2 struct {
type T2 :struct {
b: i32
}
type I1 interface {
type I1 :interface {
f()
}
type I2 interface {
type I2 :interface {
f2()
}

View File

@@ -40,7 +40,7 @@ func LifeInit(w, h, s: int) {
}
}
type DIR struct {
type DIR :struct {
x: int
y: int
}

View File

@@ -1,8 +1,8 @@
// 版权 @2021 凹语言 作者。保留所有权利。
type FP func(i: i32) => i32
type FP :func(i: i32) => i32
type ST struct {
type ST :struct {
i: i32
}

View File

@@ -14,6 +14,6 @@ func Swap(i, j: ST) => (ST, ST) {
return j, i
}
type ST struct {
type ST :struct {
i, j: i32
}

View File

@@ -146,7 +146,7 @@ func test_array(a: int, b: int) {
println("arr[", b, "][", a, "] = ", arr[b][a])
}
type t0 struct {
type t0 :struct {
a: i64
b: i32
c: [4]f64
@@ -181,7 +181,7 @@ func test_struct1(a: int, b: int, c: int) {
}
}
type struct_t0 struct {
type struct_t0 :struct {
arr0: [16]int
arr1: [16]f32
}
@@ -234,7 +234,7 @@ func test_struct4 {
}
}
type fff32 f32
type fff32 :f32
global arr0: [32]fff32
global arr1: [32]fff32
@@ -359,7 +359,7 @@ func test_global_consts() {
}
}
type ty0 struct {
type ty0 :struct {
v0: int
v1: f64
}

View File

@@ -10,11 +10,11 @@ func main {
println(j.b)
}
type sp struct {
type sp :struct {
a: *i32
}
type sc struct {
type sc :struct {
b: i32
sp
}

View File

@@ -4,7 +4,7 @@ import (
"pkg/mypkg"
)
type ST struct {
type ST :struct {
A: string
B: i32
}

View File

@@ -1,6 +1,6 @@
// 版权 @2022 hello 作者。保留所有权利。
type ST struct {
type ST :struct {
A: i32
B: string
}

View File

@@ -17,11 +17,11 @@ buf为帧缓存指针
func updateCanvas_JS(id: u32, buf: *u32)
//画布事件回调函数原型
type OnTouch func(x, y: u32)
type OnKey func(key: u32)
type OnTouch :func(x, y: u32)
type OnKey :func(key: u32)
//画布对象
type Canvas struct {
type Canvas :struct {
device_id: u32 //画布对象对应的网页DOM对象id
width: u32 //画布宽度,以像素为单位
height: u32 //画布高度,以像素为单位
@@ -29,7 +29,7 @@ type Canvas struct {
}
//画布事件
type CanvasEvents struct {
type CanvasEvents :struct {
Device_id: u32 //画布设备ID
OnMouseDown: OnTouch //鼠标按下时的回调处理函数
OnMouseUp: OnTouch //鼠标松开时的回调处理函数

View File

@@ -17,7 +17,7 @@ func Canvas_OnKeyUp(id, key: u32) {
canvas.OnKeyUp(id, key)
}
type Position struct {
type Position :struct {
x, y: i32
}
@@ -41,7 +41,7 @@ const (
global Dirs: [5]Position
type GameState struct {
type GameState :struct {
w, h: i32
scale: i32
grid: []u8

View File

@@ -30,11 +30,11 @@ func main {
println(Info.name, " ", Info.age) //李四 66
}
type sp struct {
type sp :struct {
a: *i32
}
type sc struct {
type sc :struct {
b: i32
sp
}

View File

@@ -35,7 +35,7 @@ const (
)
// Table is a 256-word table representing the polynomial for efficient processing.
type Table [256]uint32
type Table :[256]uint32
// This file makes use of functions implemented in architecture-specific files.
// The interface that they implement is as follows:
@@ -148,7 +148,7 @@ func MakeTable(poly: uint32) => *Table {
}
// digest represents the partial evaluation of a checksum.
type digest struct {
type digest :struct {
crc: uint32
tab: *Table
}

View File

@@ -47,7 +47,7 @@ func simpleUpdate(crc: uint32, tab: *Table, p: []byte) => uint32 {
const slicing8Cutoff = 16
// slicing8Table is array of 8 Tables, used by the slicing-by-8 algorithm.
type slicing8Table [8]Table
type slicing8Table :[8]Table
// slicingMakeTable constructs a slicing8Table for the specified polynomial. The
// table is suitable for use with the slicing-by-8 algorithm (slicingUpdate).

View File

@@ -4,13 +4,13 @@ import "io"
// Replacer replaces a list of strings with replacements.
// It is safe for concurrent use by multiple goroutines.
type Replacer struct {
type Replacer :struct {
r: replacer
oldnew: []string
}
// replacer is the interface that a replacement algorithm needs to implement.
type replacer interface {
type replacer :interface {
Replace(s: string) => string
WriteString(w: io.Writer, s: string) => (n: int, err: error)
}
@@ -117,7 +117,7 @@ func Replacer.WriteString(w: io.Writer, s: string) => (n: int, err: error) {
// n2 and n3; n4's child is n5; n6's child is n7. Nodes n0, n1 and n4 (marked
// with a trailing "-") are partial keys, and nodes n2, n3, n5, n6 and n7
// (marked with a trailing "+") are complete keys.
type trieNode struct {
type trieNode :struct {
// value is the value of the trie node's key/value pair. It is empty if
// this node is not a complete key.
value: string
@@ -255,7 +255,7 @@ func genericReplacer.lookup(s: string, ignoreRoot: bool) => (val: string, keylen
// genericReplacer is the fully generic algorithm.
// It's used as a fallback when nothing faster can be used.
type genericReplacer struct {
type genericReplacer :struct {
root: trieNode
// tableSize is the size of a trie node's lookup table. It is the number
// of unique key bytes.
@@ -296,7 +296,7 @@ func makeGenericReplacer(oldnew: []string) => *genericReplacer {
return r
}
type appendSliceWriter []byte
type appendSliceWriter :[]byte
// Write writes to the buffer to satisfy io.Writer.
func appendSliceWriter.Write(p: []byte) => (int, error) {
@@ -310,7 +310,7 @@ func appendSliceWriter.WriteString(s: string) => (int, error) {
return len(s), nil
}
type stringWriter struct {
type stringWriter :struct {
w: io.Writer
}
@@ -377,7 +377,7 @@ func genericReplacer.WriteString(w: io.Writer, s: string) => (n: int, err: error
// singleStringReplacer is the implementation that's used when there is only
// one string to replace (and that string has more than one byte).
type singleStringReplacer struct {
type singleStringReplacer :struct {
finder: *stringFinder
// value is the new string that replaces that pattern when it's found.
value: string
@@ -438,7 +438,7 @@ func singleStringReplacer.WriteString(w: io.Writer, s: string) => (n: int, err:
// byteReplacer is the implementation that's used when all the "old"
// and "new" values are single ASCII bytes.
// The array contains replacement bytes indexed by old byte.
type byteReplacer [256]byte
type byteReplacer :[256]byte
func byteReplacer.Replace(s: string) => string {
r := this
@@ -493,7 +493,7 @@ func byteReplacer.WriteString(w: io.Writer, s: string) => (n: int, err: error) {
// byteStringReplacer is the implementation that's used when all the
// "old" values are single ASCII bytes but the "new" values vary in size.
type byteStringReplacer struct {
type byteStringReplacer :struct {
// replacements contains replacement byte slices indexed by old byte.
// A nil []byte means that the old byte should not be replaced.
replacements: [256][]byte

View File

@@ -380,7 +380,7 @@ func Fields(s: string) => []string {
func FieldsFunc(s: string, f: func(rune) => bool) => []string {
// A span is used to record a slice of s of the form s[start:end].
// The start index is inclusive and the end index is exclusive.
type span struct {
type span :struct {
start: int
end: int
}
@@ -859,7 +859,7 @@ func lastIndexFunc(s: string, f: func(rune) => bool, truth: bool) => int {
// ensuring that any non-ASCII character will be reported as not in the set.
// This allocates a total of 32 bytes even though the upper half
// is unused to avoid bounds checks in asciiSet.contains.
type asciiSet [8]uint32
type asciiSet :[8]uint32
// makeASCIISet creates a set of ASCII characters and reports whether all
// characters in chars are ASCII.