checktype.go 2.32 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
 - GoRoutines Declarations outside main function
12
 - Interface
13
 - Map
Hugo Moreau's avatar
Hugo Moreau committed
14
15
16
 - Non-integer variable
 - Panic
 - Pointer
17
 - Select
Hugo Moreau's avatar
Hugo Moreau committed
18
19
20
 - Slice
 - Struct
 - Switch
21
22
23
*/

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

// 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 {
36
					panic("Non-integer values are not supported.")
37
				}
38
39
40
41
42
43
44
			case *ast.ArrayType:
				switch ident := rhn.Elt.(type) {
				case *ast.Ident:
					if ident.Name != "int" {
						panic("Not int arrays are not supported.")
					}
				}
45
			}
Hugo Moreau's avatar
Hugo Moreau committed
46
47
48
49
50
51
			switch lhn := node.Lhs[i].(type) {
			case *ast.Ident:
				if strings.Contains(lhn.Name, "G2P_tmp_") {
					panic("Variable name must not contain \"G2P_tmp_\"")
				}
			}
52
		}
53
54
	case *ast.FuncDecl:
		t.currentFunction = node.Name.Obj
55
56
57
58
59
60
61
	case *ast.FuncType:
		for _, elmt := range node.Params.List {
			switch elmt.Type.(type) {
			case *ast.ArrayType:
				panic("Int array as argument in functions are not supported.")
			}
		}
62
63
64
65
66
67
68
69
70
	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.")
		}
71
72
	case *ast.Ident:
		if node.Name == "panic" {
73
			panic("Panics are not supported.")
74
		}
Hugo Moreau's avatar
Hugo Moreau committed
75
	case *ast.InterfaceType:
76
		panic("Interfaces are not supported.")
77
	case *ast.MapType:
78
		panic("Maps are not supported.")
Hugo Moreau's avatar
Hugo Moreau committed
79
	case *ast.SliceExpr:
80
		panic("Slices are not supported.")
Hugo Moreau's avatar
Hugo Moreau committed
81
	case *ast.StarExpr:
82
		panic("Pointers are not supported.")
83
	case *ast.StructType:
84
		panic("Structs are not supported.")
85
	case *ast.SwitchStmt:
86
		panic("Switch are not supported.")
87
88
89
90
91
92
93
94
95
	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.")
				}
			}
		}
96
97
98
99
100
101
102
	}
	return true
}

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