checktype.go 2.1 KB
Newer Older
1
2
3
4
5
package transform

import (
	"go/ast"
	"go/token"
Hugo Moreau's avatar
Hugo Moreau committed
6
	"strings"
7
8
9
)

/*
10
The TypeChecker triggers errors for uses of :
11
 - Array
Hugo Moreau's avatar
Hugo Moreau committed
12
 - Channel
13
 - GoRoutines Declarations outside main function
14
 - Interface
15
 - Map
Hugo Moreau's avatar
Hugo Moreau committed
16
17
18
 - Non-integer variable
 - Panic
 - Pointer
19
 - Select
Hugo Moreau's avatar
Hugo Moreau committed
20
21
22
 - Slice
 - Struct
 - Switch
23
24
25
*/

type TypeChecker struct {
26
	currentFunction *ast.Object
27
28
29
30
31
32
33
34
35
36
37
}

// Pre traversal check if there is use of variable other than integers.
func (t *TypeChecker) Pre(meta *Meta, v *Visitor) bool {
	c := v.Cursor()
	switch node := c.Node().(type) {
	case *ast.AssignStmt:
		for i := 0; i < len(node.Rhs); i++ {
			switch rhn := node.Rhs[i].(type) {
			case *ast.BasicLit:
				if rhn.Kind != token.INT {
38
					panic("Non-integer values are not supported.")
39
				}
40
			case *ast.CompositeLit:
41
				panic("Arrays are not supported.")
42
			}
Hugo Moreau's avatar
Hugo Moreau committed
43
44
45
46
47
48
			switch lhn := node.Lhs[i].(type) {
			case *ast.Ident:
				if strings.Contains(lhn.Name, "G2P_tmp_") {
					panic("Variable name must not contain \"G2P_tmp_\"")
				}
			}
49
		}
Hugo Moreau's avatar
Hugo Moreau committed
50
	case *ast.ChanType:
51
		panic("Channels are not supported.")
52
53
54
55
56
57
58
59
60
61
62
	case *ast.FuncDecl:
		t.currentFunction = node.Name.Obj
	case *ast.GoStmt:
		switch c.Parent().(type) {
		case *ast.BlockStmt:
			if t.currentFunction.Name != "main" {
				panic("GoRoutines are not supported outside of main declaration.")
			}
		default:
			panic("GoRoutines are not supported outside of main declaration.")
		}
63
64
	case *ast.Ident:
		if node.Name == "panic" {
65
			panic("Panics are not supported.")
66
		}
Hugo Moreau's avatar
Hugo Moreau committed
67
	case *ast.InterfaceType:
68
		panic("Interfaces are not supported.")
69
	case *ast.MapType:
70
		panic("Maps are not supported.")
Hugo Moreau's avatar
Hugo Moreau committed
71
	case *ast.SliceExpr:
72
		panic("Slices are not supported.")
Hugo Moreau's avatar
Hugo Moreau committed
73
	case *ast.StarExpr:
74
		panic("Pointers are not supported.")
75
	case *ast.StructType:
76
		panic("Structs are not supported.")
77
	case *ast.SwitchStmt:
78
		panic("Switch are not supported.")
79
80
81
82
83
84
85
86
87
	case *ast.ValueSpec:
		for i := 0; i < len(node.Values); i++ {
			switch value := node.Values[i].(type) {
			case *ast.BasicLit:
				if value.Kind != token.INT {
					panic("Non integer global values are not supported.")
				}
			}
		}
88
89
90
91
92
93
94
	}
	return true
}

func (TypeChecker) Post(meta *Meta, v *Visitor) bool {
	return true
}