summaryrefslogtreecommitdiff
path: root/src/main.go
blob: ee7f69b79b841cc049a50f287ab0f642b9818a5f (plain)
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
116
117
118
119
120
121
package main

import (
	"fmt"
	"strconv"
	"regexp"
	"os"
) 

func readfile(path string) []string {

	var raw []string;
	reg := regexp.MustCompile(`\s`)

	dat, err := os.ReadFile(path);
	if (err != nil) {
		panic("failed to read file");
	}

	/* FIXME: Find a better solution */
	tmp := reg.Split(string(dat), -1);

	for i := range tmp{
		if tmp[i] != "" {
			raw = append(raw, tmp[i]);
		} 
	};

	return raw;
}

func interpret(raw[]string) {
	var err error;
	var number int;
	var stack[]int;
	var skip_to_end bool;

	for i := 0; i < len(raw); i++ {
		length := len(stack);
		/* Conditional looping */
		if (skip_to_end && raw[i] != "end") {
			continue;
		}
		number, err = strconv.Atoi(raw[i]);
		if err == nil {
			stack = append(stack, number);
			continue; 
		}

		switch raw[i] {
		case "+":
			if length < 2 {
				panic("failed to plus: stack underflow");
			}
			stack[length - 2] = stack[length - 1] + stack[length - 2]
			stack = stack[:length - 1];
		case "-":
			if length < 2 {
				panic("failed to minus: stack underflow");
			}
			stack[length - 2] = stack[length - 1] - stack[length - 2]
			stack = stack[:length - 1];
		case "=":
			if length < 2 {
				panic("failed to check equality: stack underflow");
			}
			if (stack[length - 1] == stack[length - 2]) {
				stack = append(stack, -1);
			} else {
				stack = append(stack, 0);
			}

		case ".":
			if length < 1 {
				panic("failed to dump: stack underflow");
			}
			fmt.Println(stack[length - 1]);
			stack = stack[:length - 1];
		case "if":
			if length < 1 {
				panic("failed to if: stack underflow");
			}
			if (stack[length - 1] == 0) {
				skip_to_end = true;
			}
			stack = stack[:length - 1];
		case "end":
			skip_to_end = false;

		default:
			panic("invalid word");
		}
	} 
}

func main() {
	var file string;
	argv := os.Args;
	argc := len(argv);
	compile_flg := false;

	switch argc {
	case 3:
		if argv[1] != "-S" {
			panic("Invalid usage");
		}
		compile_flg = true;
		fallthrough;
	case 2:
		file = argv[argc - 1];
	default:
		panic("Invaid usage");
	}

	output := readfile(file);
	if (compile_flg) {
		panic("Not Implemented");
	} else {
		interpret(output);
	}
}