예제 #1
0
파일: decls.go 프로젝트: 8l/leaf
// var-ident [ "[" [ int ] "]" ] [ type-ident ] = var-init
func (p *Parser) parseVarSpec() *ast.Var {
	p.push("var-spec")
	defer p.pop()

	ret := new(ast.Var)
	err := func() *ast.Var {
		p.skipUntil(tt.Semi)
		return ret
	}

	if !p.expect(tt.Ident) {
		return err()
	}
	t := p.last()
	ret.Name = t.Lit
	ret.NameToken = t

	if p.ahead(tt.Lbrack) || p.ahead(tt.Ident) {
		if !p.parseVarType(ret) {
			return err()
		}
	}

	if p.accept(tt.Assign) {
		if !p.parseVarValue(ret) {
			return err()
		}
	}

	if !p.expect(tt.Semi) {
		return err()
	}

	return ret
}
예제 #2
0
파일: decls.go 프로젝트: 8l/leaf
func (p *Parser) parseVarType(v *ast.Var) bool {
	p.push("var-type")
	defer p.pop()

	if p.accept(tt.Lbrack) {
		v.IsArray = true
		if p.accept(tt.Int) {
			v.SizeToken = p.last()
		}

		if !p.expect(tt.Rbrack) {
			return false
		}
	}

	if p.accept(tt.Ident) {
		t := p.last()
		v.TypeToken = t
		v.Type = t.Lit
	} else if v.IsArray {
		return false
	}

	return true
}
예제 #3
0
파일: decls.go 프로젝트: 8l/leaf
func (p *Parser) parseVarValue(v *ast.Var) bool {
	if p.accept(tt.Lbrace) {
		p.extend("var-init-array")
		defer p.pop()
		for {
			if p.accept(tt.Rbrace) {
				break
			}

			if p.accept(tt.Int) || p.accept(tt.Char) || p.accept(tt.Float) {
				v.InitValues = append(v.InitValues, p.last())
			} else {
				p.expecting("init values")
				return false
			}

			if p.accept(tt.Comma) {
				continue
			}

			if !p.ahead(tt.Rbrace) {
				p.expecting("comma or right brace")
				return false
			}
		}
	} else if p.accept(tt.String) {
		p.extend("var-init-string")
		defer p.pop()
		v.InitValue = p.last()
	} else if p.accept(tt.Int) || p.accept(tt.Char) || p.accept(tt.Float) {
		p.extend("var-init-single")
		defer p.pop()
		v.InitValue = p.last()
	} else {
		p.expecting("init var value")
		return false
	}

	return true
}