@@ -10,181 +10,128 @@ import (
1010)
1111
1212type Interpreter struct {
13- variables map [string ]int
13+ variables map [string ]interface {}
1414}
1515
1616// NewInterpreter initializes an interpreter
1717func NewInterpreter () * Interpreter {
18- return & Interpreter {variables : make (map [string ]int )}
18+ return & Interpreter {variables : make (map [string ]interface {} )}
1919}
2020
2121// Execute parses and executes a single line of code
2222func (i * Interpreter ) Execute (line string ) {
2323 tokens := strings .Fields (line )
24-
2524 if len (tokens ) == 0 {
2625 return
2726 }
2827
2928 switch tokens [0 ] {
3029 case "kemon" :
31- // Ensure that the syntax is correct
3230 if len (tokens ) < 3 || tokens [1 ] != "achis" {
3331 fmt .Println ("bhul hoye gelo vai check kor ekbar" )
3432 return
3533 }
36-
37- // Get the argument after 'kemon achis'
3834 arg := strings .Join (tokens [2 :], " " )
3935
40- // Case 1: If the argument is a valid expression (e.g., a + b)
41- // We will split the argument based on spaces and evaluate it as an expression
42- if strings .Contains (arg , "+" ) || strings .Contains (arg , "-" ) || strings .Contains (arg , "*" ) || strings .Contains (arg , "/" ) {
43- tokens := splitExpression (arg )
44- result , err := i .evaluateExpression (tokens )
45- if err != nil {
46- fmt .Println ("bhul hoye gelo vai check kor ekbar" )
36+ // Check if the argument is a quoted string
37+ if strings .HasPrefix (arg , "\" " ) && strings .HasSuffix (arg , "\" " ) {
38+ fmt .Println (arg [1 : len (arg )- 1 ]) // Remove the quotes for display
39+ return
40+ }
41+
42+ // If not a string, evaluate the expression
43+ value , err := i .evaluateExpression (strings .Fields (arg ))
44+ if err == nil {
45+ fmt .Println (value )
46+ } else {
47+ // Check if it's a variable
48+ if value , ok := i .variables [arg ]; ok {
49+ fmt .Println (value )
4750 } else {
48- fmt .Println (result )
51+ fmt .Println ("bhul hoye gelo vai check kor ekbar" )
4952 }
50- } else if strings .HasPrefix (arg , `"` ) && strings .HasSuffix (arg , `"` ) {
51- // Case 2: Argument is a string literal (enclosed in double quotes)
52- // Remove the surrounding quotes and print the value
53- fmt .Println (arg [1 : len (arg )- 1 ])
54- } else if _ , err := strconv .Atoi (arg ); err == nil {
55- // Case 3: Argument is a number (valid as an integer)
56- fmt .Println (arg )
57- } else {
58- // Case 4: Invalid expression or unknown token
59- fmt .Println ("bhul hoye gelo vai check kor ekbar" )
6053 }
6154
62- fmt .Println ("weee ko peyechis ebar porte bos" )
63-
6455 case "bol" :
6556 if len (tokens ) != 3 || tokens [1 ] != "bhai" {
6657 fmt .Println ("bhul hoye gelo vai check kor ekbar" )
6758 return
6859 }
6960 varName := tokens [2 ]
70- fmt .Printf ("Enter value for %s: " , varName )
61+ fmt .Printf (`Value bolo %s er =>: ` , varName )
7162 var input string
7263 fmt .Scanln (& input )
73- value , err := strconv .Atoi (input )
74- if err != nil {
75- fmt .Println ("bhul hoye gelo vai check kor ekbar: invalid number" )
64+
65+ // Handle string input properly (strip the quotes if present)
66+ if strings .HasPrefix (input , "\" " ) && strings .HasSuffix (input , "\" " ) {
67+ i .variables [varName ] = input [1 : len (input )- 1 ] // Store the string without quotes
68+ } else if value , err := strconv .Atoi (input ); err == nil {
69+ i .variables [varName ] = value // Store the integer value
70+ } else {
71+ fmt .Println ("bhul hoye gelo vai check kor ekbar: invalid value" )
7672 return
7773 }
78- i .variables [varName ] = value
7974
8075 case "dyakh" :
81- // Syntax: dyakh jodi <condition>: <command> ar nahole: <command>
8276 if len (tokens ) < 4 || tokens [1 ] != "jodi" || ! strings .Contains (line , "ar nahole:" ) {
8377 fmt .Println ("bhul hoye gelo vai check kor ekbar: Invalid conditional syntax" )
8478 return
8579 }
8680
87- // Split into condition and commands
8881 parts := strings .Split (line , "ar nahole:" )
8982 if len (parts ) != 2 {
9083 fmt .Println ("bhul hoye gelo vai check kor ekbar: Missing 'ar nahole'" )
9184 return
9285 }
9386
94- ifPart := strings .TrimSpace (parts [0 ]) // "dyakh jodi <condition>: <command>"
95- elsePart := strings .TrimSpace (parts [1 ]) // "<command>"
87+ ifPart := strings .TrimSpace (parts [0 ])
88+ elsePart := strings .TrimSpace (parts [1 ])
9689
97- // Extract the condition and command for the "if" part
9890 ifTokens := strings .SplitN (ifPart , ":" , 2 )
9991 if len (ifTokens ) != 2 {
10092 fmt .Println ("bhul hoye gelo vai check kor ekbar: Missing ':' in 'dyakh jodi'" )
10193 return
10294 }
10395
104- condition := strings .TrimSpace (strings .Join (strings .Fields (ifTokens [0 ])[2 :], " " )) // Extract the condition
105- ifCommand := strings .TrimSpace (ifTokens [1 ]) // Command after ':'
96+ condition := strings .TrimSpace (strings .Join (strings .Fields (ifTokens [0 ])[2 :], " " ))
97+ ifCommand := strings .TrimSpace (ifTokens [1 ])
10698
107- // Evaluate the condition
108- condValue , err := i .evaluateExpression (strings .Fields (condition ))
99+ condValue , err := i .evaluateCondition (condition )
109100 if err != nil {
110- fmt .Println ("bhul hoye gelo vai check kor ekbar: Error evaluating condition:" , err )
101+ fmt .Println ("bhul hoye gelo vai check kor ekbar: Error evaluating condition" )
111102 return
112103 }
113104
114- // Execute the appropriate command
115- if condValue != 0 {
116- i .Execute (ifCommand ) // Execute the command after 'dyakh jodi'
105+ if condValue {
106+ i .Execute (ifCommand )
117107 } else {
118- // If the elsePart is a string surrounded by quotes, remove them
119- if strings .HasPrefix (elsePart , `"` ) && strings .HasSuffix (elsePart , `"` ) {
120- // Remove the surrounding quotes and print the result
121- fmt .Println (elsePart [1 : len (elsePart )- 1 ])
108+ if strings .HasPrefix (elsePart , "\" " ) && strings .HasSuffix (elsePart , "\" " ) {
109+ fmt .Println (elsePart [1 : len (elsePart )- 1 ]) // Remove quotes for printing
122110 } else {
123- // Otherwise, just execute the command in elsePart
124111 i .Execute (elsePart )
125112 }
126113 }
127114
128- case "ar" :
129- // Syntax: ar nahole
130- if len (tokens ) != 2 || tokens [1 ] != "nahole" {
131- fmt .Println ("bhul hoye gelo vai check kor ekbar: Invalid else syntax" )
132- return
133- }
134-
135- // Execute the next block
136- // Now it's just printing the raw string contents without quotes
137- fmt .Println ("ar nahole: Execute the else block" )
138-
139115 default :
140- if len (tokens ) < 3 || tokens [1 ] != "=" {
141- fmt .Println ("bhul hoye gelo vai check kor ekbar" )
142- return
143- }
144- varName := tokens [0 ]
145- expression := tokens [2 :]
146- value , err := i .evaluateExpression (expression )
147- if err != nil {
148- fmt .Println ("bhul hoye gelo vai check kor ekbar:" , err )
149- return
150- }
151- i .variables [varName ] = value
152- fmt .Println ("weee ko peyechis ebar porte bos" )
116+ fmt .Println ("bhul hoye gelo vai check kor ekbar: Unknown command" )
153117 }
154118}
155119
156- func splitExpression (expression string ) []string {
157- // Split based on operators (+, -, *, /)
158- var tokens []string
159- var currentToken string
160- for _ , ch := range expression {
161- if ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '>' || ch == '<' || ch == '=' || ch == '|' || ch == '&' {
162- if len (currentToken ) > 0 {
163- tokens = append (tokens , currentToken )
164- }
165- tokens = append (tokens , string (ch ))
166- currentToken = ""
167- } else if ch != ' ' {
168- currentToken += string (ch )
169- }
170- }
171- if len (currentToken ) > 0 {
172- tokens = append (tokens , currentToken )
173- }
174- return tokens
175- }
176-
177120func (i * Interpreter ) evaluateExpression (tokens []string ) (int , error ) {
178- // If there's only one token, return its value
179121 if len (tokens ) == 1 {
180- // Handle the case where the token is a string
181- if tokens [0 ][0 ] == '"' && tokens [0 ][len (tokens [0 ])- 1 ] == '"' {
182- return 1 , nil // Consider string as "true" for conditional purposes
122+ if value , ok := i .variables [tokens [0 ]]; ok {
123+ switch v := value .(type ) {
124+ case int :
125+ return v , nil
126+ case string :
127+ return 0 , fmt .Errorf ("expected an integer, but got a string" )
128+ default :
129+ return 0 , fmt .Errorf ("invalid type for evaluation" )
130+ }
183131 }
184- return i . getValue (tokens [0 ])
132+ return strconv . Atoi (tokens [0 ])
185133 }
186134
187- // Handle binary operations like a + b
188135 if len (tokens ) == 3 {
189136 left , err := i .getValue (tokens [0 ])
190137 if err != nil {
@@ -206,31 +153,6 @@ func (i *Interpreter) evaluateExpression(tokens []string) (int, error) {
206153 return 0 , fmt .Errorf ("division by zero" )
207154 }
208155 return left / right , nil
209- case ">" :
210- if left > right {
211- return 1 , nil
212- }
213- return 0 , nil
214- case "<" :
215- if left < right {
216- return 1 , nil
217- }
218- return 0 , nil
219- case "==" :
220- if left == right {
221- return 1 , nil
222- }
223- return 0 , nil
224- case "||" :
225- if left != 0 || right != 0 {
226- return 1 , nil
227- }
228- return 0 , nil
229- case "&&" :
230- if left != 0 && right != 0 {
231- return 1 , nil
232- }
233- return 0 , nil
234156 default :
235157 return 0 , fmt .Errorf ("unknown operator '%s'" , tokens [1 ])
236158 }
@@ -239,16 +161,53 @@ func (i *Interpreter) evaluateExpression(tokens []string) (int, error) {
239161 return 0 , fmt .Errorf ("invalid expression" )
240162}
241163
164+ func (i * Interpreter ) evaluateCondition (condition string ) (bool , error ) {
165+ tokens := strings .Fields (condition )
166+ if len (tokens ) != 3 {
167+ return false , fmt .Errorf ("invalid condition syntax" )
168+ }
169+
170+ left , err := i .getValue (tokens [0 ])
171+ if err != nil {
172+ return false , err
173+ }
174+ right , err := i .getValue (tokens [2 ])
175+ if err != nil {
176+ return false , err
177+ }
178+
179+ switch tokens [1 ] {
180+ case ">" :
181+ return left > right , nil
182+ case "<" :
183+ return left < right , nil
184+ case ">=" :
185+ return left >= right , nil
186+ case "<=" :
187+ return left <= right , nil
188+ case "==" :
189+ return left == right , nil
190+ case "!=" :
191+ return left != right , nil
192+ default :
193+ return false , fmt .Errorf ("unknown operator '%s'" , tokens [1 ])
194+ }
195+ }
196+
242197func (i * Interpreter ) getValue (token string ) (int , error ) {
243- // Check if token is a number
244198 if value , err := strconv .Atoi (token ); err == nil {
245199 return value , nil
246200 }
247- // Check if token is a variable
248201 if value , exists := i .variables [token ]; exists {
249- return value , nil
202+ switch v := value .(type ) {
203+ case int :
204+ return v , nil
205+ case string :
206+ return 0 , fmt .Errorf ("expected an integer, but got a string" )
207+ default :
208+ return 0 , fmt .Errorf ("unknown variable '%s'" , token )
209+ }
250210 }
251- // Return error if token is unknown
252211 return 0 , fmt .Errorf ("unknown variable '%s'" , token )
253212}
254213
@@ -258,7 +217,7 @@ func main() {
258217 flag .Parse ()
259218
260219 if * version {
261- fmt .Println ("Gola Compiler v1.0.1 " )
220+ fmt .Println ("Gola Compiler v1.0.2 " )
262221 return
263222 }
264223 if * help {
@@ -304,7 +263,7 @@ func main() {
304263#+# #+# #+# #+# #+# #+# #+#
305264######## ######## ########## ### ###
306265
307- ` )
266+ ` )
308267 fmt .Println ("Type 'exit' to quit." )
309268 scanner := bufio .NewScanner (os .Stdin )
310269 interpreter := NewInterpreter ()
0 commit comments