File: lvalue.go

package info (click to toggle)
mumax3 3.10-9
  • links: PTS, VCS
  • area: contrib
  • in suites: trixie
  • size: 7,596 kB
  • sloc: makefile: 181; ansic: 155; sh: 77
file content (69 lines) | stat: -rw-r--r-- 1,367 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package script

import (
	"go/ast"
	"reflect"
)

// left-hand value in (single) assign statement
type LValue interface {
	Expr
	SetValue(interface{}) // assigns a new value
}

func (w *World) compileLvalue(lhs ast.Node) LValue {
	switch lhs := lhs.(type) {
	default:
		panic(err(lhs.Pos(), "cannot assign to", typ(lhs)))
	case *ast.Ident:
		if l, ok := w.resolve(lhs.Pos(), lhs.Name).(LValue); ok {
			return l
		} else {
			panic(err(lhs.Pos(), "cannot assign to", lhs.Name))
		}
	}
}

type reflectLvalue struct {
	elem reflect.Value
}

// general lvalue implementation using reflect.
// lhs must be settable, e.g. address of something:
// 	var x float64
// 	newReflectLValue(&x)
func newReflectLvalue(addr interface{}) LValue {
	elem := reflect.ValueOf(addr).Elem()
	if elem.Kind() == 0 {
		panic("variable/constant needs to be passed as pointer to addressable value")
	}
	return &reflectLvalue{elem}
}

func (l *reflectLvalue) Eval() interface{} {
	return l.elem.Interface()
}

func (l *reflectLvalue) Type() reflect.Type {
	return l.elem.Type()
}

func (l *reflectLvalue) SetValue(rvalue interface{}) {
	l.elem.Set(reflect.ValueOf(rvalue))
}

func (l *reflectLvalue) Child() []Expr {
	return nil
}

func (l *reflectLvalue) Fix() Expr {
	return NewConst(l)
}

type TVar struct {
	LValue
}

func (t *TVar) Fix() Expr {
	return t // only variable that's not fixed
}