Exemple #1
0
func (a *Asm) readLs(fn *bytecode.Fn) {
	// While the L section is not reached
	for l, ok := a.getLine(false); ok && l != "[i]"; l, ok = a.getLine(false) {
		var i int64
		i, a.err = strconv.ParseInt(l, 10, 64)
		fn.Ls = append(fn.Ls, i)
	}
	a.readIs(fn)
}
Exemple #2
0
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)
}