예제 #1
0
파일: asm.go 프로젝트: jmptrader/agora
func (a *Asm) readKs(fn *bytecode.Fn) {
	// While the L section is not reached
	for l, ok := a.getLine(true); ok && l != "[l]"; l, ok = a.getLine(true) {
		var err error
		k := new(bytecode.K)
		// The K Type is the first character of the line
		k.Type = bytecode.KType(l[0])
		switch k.Type {
		case bytecode.KtInteger, bytecode.KtBoolean:
			// Finish the trim
			val := strings.TrimRight(l[1:], " \t")
			k.Val, err = strconv.ParseInt(val, 10, 64)
		case bytecode.KtFloat:
			val := strings.TrimRight(l[1:], " \t")
			k.Val, err = strconv.ParseFloat(val, 64)
		default:
			// Untrimmed string value
			k.Val = l[1:]
		}
		fn.Ks = append(fn.Ks, k)
		if err != nil && a.err == nil {
			a.err = err
		}
	}
	a.readLs(fn)
}
예제 #2
0
파일: emitter.go 프로젝트: jmptrader/agora
func (e *Emitter) registerK(fn *bytecode.Fn, val interface{}, isName bool, local bool) uint64 {
	var kt bytecode.KType
	s, ok := val.(string)
	if ok {
		if isName {
			val = s
			kt = bytecode.KtString
		} else if s[0] == '"' || s[0] == '`' {
			// Unquote the string, keeping escaped characters
			var err error
			s, err = strconv.Unquote(s)
			e.assert(err == nil, err)
			val = s
			kt = bytecode.KtString
		} else if strings.Index(s, ".") >= 0 {
			val, e.err = strconv.ParseFloat(s, 64)
			kt = bytecode.KtFloat
		} else {
			val, e.err = strconv.ParseInt(s, 10, 64)
			kt = bytecode.KtInteger
		}
	} else {
		kt = bytecode.KtBoolean
		if v := val.(bool); v {
			s = "true"
			val = int64(1)
		} else {
			s = "false"
			val = int64(0)
		}
	}
	// Create the map slot for this function if this is its first symbol
	m, ok := e.kMap[fn]
	if !ok {
		m = make(map[kId]int)
		e.kMap[fn] = m
	}
	// Check if this symbol already exists for this fn with this same type, otherwise add it to its Ks
	i, ok := m[kId{s, kt}]
	if !ok {
		i = len(m)
		m[kId{s, kt}] = i
		fn.Ks = append(fn.Ks, &bytecode.K{Type: kt, Val: val})
	}
	// If this is a local definition, add the K index to this function's L table.
	// It can't have duplicates by definition, because it would have been caught as an
	// error in the parser stage.
	if local {
		fn.Ls = append(fn.Ls, int64(i))
	}
	return uint64(i)
}