-
Notifications
You must be signed in to change notification settings - Fork 1
/
lexer.go
115 lines (103 loc) · 2.95 KB
/
lexer.go
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package rocket
type Program string
func lex (program Program) []Unit {
currentIndex := 0;
unitList := []Unit{}
for currentIndex < len(program) {
unit := string(program[currentIndex])
unitType := determineType(unit)
switch unitType {
case "INTERGER":
nextType := determineType(program.peek(currentIndex+1))
if nextType == "INTERGER" {
completeUnit := program.peekLong(currentIndex, "INTERGER")
unitList = append(unitList, completeUnit)
currentIndex += len(completeUnit.cargo)
} else {
unitList = append(unitList, Digits.getBaseUnit(unit))
currentIndex++
}
case "LETTER": //not needed for now
break;
case "OPERATOR":
nextUnit := program.peek(currentIndex+1)
nextType := determineType(program.peek(currentIndex+1))
if nextType == "OPERATOR" {
newOperator := unit+nextUnit
definition := TwoCharacterSymbols.getBaseUnit(newOperator)
if definition.cargo != "BASE_LOOKUP_ERR" {
unitList = append(unitList,definition)
currentIndex += 2
} else {
unitList = append(unitList,OneCharacterSymbols.getBaseUnit(unit))
currentIndex ++
}
} else {
unitList = append(unitList,OneCharacterSymbols.getBaseUnit(unit))
currentIndex++
}
case "SYMBOL":
unitList = append(unitList, OneCharacterSymbols.getBaseUnit(unit))
currentIndex++
}
}
return unitList
}
func (program Program) peek (index int) string {
return string(program[index])
}
func (program Program) peekLong (startIndex int, unitType string) Unit {
currentIndex := startIndex
accum := ""
for ;; {
if(currentIndex >= len(program)) {
return Unit{cargo: accum, notation: unitType, unitType: unitType}
break
}
currentUnit := string(program[currentIndex])
if determineType(currentUnit) != unitType {
return Unit{cargo: accum, notation: unitType, unitType: unitType}
break
} else {
accum += currentUnit
currentIndex++
}
}
return Unit{cargo: "PEEKLONG_ERR", notation: "PEEKLONG_ERR", unitType: "INTERGER"}
}
func determineType (unit string) string {
if Digits.contains(unit) {
return "INTERGER"
}
if Letters.contains(unit) {
return "LETTER"
}
if OneCharacterSymbols.contains(unit) {
return OneCharacterSymbols.getType(unit)
}
return "UNDEFINED_TYPE"
}
func (unitTable UnitTable) contains (currentUnit string) bool {
for _, tableUnit := range unitTable {
if tableUnit.cargo == currentUnit {
return true
}
}
return false
}
func (unitTable UnitTable) getBaseUnit (currentUnit string) Unit {
for _, tableUnit := range unitTable {
if tableUnit.cargo == currentUnit {
return tableUnit
}
}
return Unit{cargo: "BASE_LOOKUP_ERR", notation: "BASE_LOOKUP_ERR", unitType: "BASE_LOOKUP_ERR"}
}
func (unitTable UnitTable) getType (currentUnit string) string {
for _, tableUnit := range unitTable {
if tableUnit.cargo == currentUnit {
return tableUnit.unitType
}
}
return "UNKNOWN_TYPE"
}