mirror of
https://gitee.com/wa-lang/wa.git
synced 2025-12-06 17:19:15 +08:00
parser 增加泛型宏参数解析; 类型定义必须 : 分隔
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ func main {
|
||||
vm.Run()
|
||||
}
|
||||
|
||||
type BrainFuck struct {
|
||||
type BrainFuck :struct {
|
||||
mem: [30000]byte
|
||||
code: string
|
||||
pos: int
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 版权 @2022 凹语言 作者。保留所有权利。
|
||||
|
||||
// BF 虚拟机
|
||||
type BrainFuck struct {
|
||||
type BrainFuck :struct {
|
||||
mem: [30000]byte
|
||||
code: string
|
||||
pos: int
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ func LifeInit(w, h, s: int) {
|
||||
}
|
||||
}
|
||||
|
||||
type DIR struct {
|
||||
type DIR :struct {
|
||||
x: int
|
||||
y: int
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,6 @@ func Swap(i, j: ST) => (ST, ST) {
|
||||
return j, i
|
||||
}
|
||||
|
||||
type ST struct {
|
||||
type ST :struct {
|
||||
i, j: i32
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"pkg/mypkg"
|
||||
)
|
||||
|
||||
type ST struct {
|
||||
type ST :struct {
|
||||
A: string
|
||||
B: i32
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 版权 @2022 hello 作者。保留所有权利。
|
||||
|
||||
type ST struct {
|
||||
type ST :struct {
|
||||
A: i32
|
||||
B: string
|
||||
}
|
||||
|
||||
@@ -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 //鼠标松开时的回调处理函数
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user