Ejemplo n.º 1
0
Archivo: special.go Proyecto: zzn01/ivy
// nextDecimalNumber64 returns the next number, which
// must fit in a non-negative int64.
func (p *Parser) nextDecimalNumber64() int64 {
	ibase, obase := p.config.Base()
	defer p.config.SetBase(ibase, obase)
	p.config.SetBase(10, obase)
	v, err := value.Parse(p.need(scan.Number).Text)
	if err != nil {
		p.errorf("%s", err)
	}
	var n int64 = -1
	switch num := v.(type) {
	case value.Int:
		n = int64(num)
	case value.BigInt:
		// The Int64 method produces undefined results if
		// the value is too large, so we must check.
		if num.Int.Sign() < 0 || num.Int.Cmp(value.MaxBigInt63) > 0 {
			p.errorf("value out of range: %v", v)
		}
		n = num.Int64()
	}
	if n < 0 {
		p.errorf("value must be a positive integer: %v", v)
	}
	return n
}
Ejemplo n.º 2
0
func (p *Parser) nextDecimalNumber() int {
	ibase, obase := p.config.Base()
	defer p.config.SetBase(ibase, obase)
	p.config.SetBase(10, obase)
	v, err := value.Parse(p.need(scan.Number).Text)
	if err != nil {
		p.errorf("%s", err)
	}
	num, ok := v.(value.Int)
	if !ok {
		p.errorf("value must be an integer: %v", v)
	}
	return int(num)
}
Ejemplo n.º 3
0
// number
//	integer
//	rational
//	variable
//	'(' Expr ')'
func (p *Parser) number(tok scan.Token) value.Expr {
	var expr value.Expr
	text := tok.Text
	switch tok.Type {
	case scan.Identifier:
		expr = p.variable(text)
	case scan.Number, scan.Rational:
		var err error
		expr, err = value.Parse(text)
		if err != nil {
			p.errorf("%s: %s", text, err)
		}
	case scan.LeftParen:
		expr = p.expr(p.next())
		tok := p.next()
		if tok.Type != scan.RightParen {
			p.errorf("expected right paren, found %s", tok)
		}
	}
	return expr
}
Ejemplo n.º 4
0
Archivo: parse.go Proyecto: db47h/ivy
// number
//	integer
//	rational
//	string
//	variable
//	'(' Expr ')'
// If the value is a string, value.Expr is nil.
func (p *Parser) number(tok scan.Token) (expr value.Expr, str string) {
	var err error
	text := tok.Text
	switch tok.Type {
	case scan.Identifier:
		expr = p.variable(text)
	case scan.String:
		str = value.ParseString(text)
	case scan.Number, scan.Rational:
		expr, err = value.Parse(p.context.Config(), text)
	case scan.LeftParen:
		expr = p.expr(p.next())
		tok := p.next()
		if tok.Type != scan.RightParen {
			p.errorf("expected right paren, found %s", tok)
		}
	}
	if err != nil {
		p.errorf("%s: %s", text, err)
	}
	return expr, str
}
Ejemplo n.º 5
0
	return value.Binary(b.left.Eval(context), b.op, b.right.Eval(context))
}

// Parser stores the state for the ivy parser.
type Parser struct {
	scanner    *scan.Scanner
	config     *config.Config
	fileName   string
	lineNum    int
	errorCount int // Number of errors.
	peekTok    scan.Token
	curTok     scan.Token // most recent token from scanner
	context    *execContext
}

var zero, _ = value.Parse("0")

// NewParser returns a new parser that will read from the scanner.
// The context must have have been created by this package's NewContext function.
func NewParser(conf *config.Config, fileName string, scanner *scan.Scanner, context value.Context) *Parser {
	return &Parser{
		scanner:  scanner,
		config:   conf,
		fileName: fileName,
		context:  context.(*execContext),
	}
}

func (p *Parser) next() scan.Token {
	tok := p.peekTok
	if tok.Type != scan.EOF {