11use crate :: ast:: {
2- ArithmeticOperator , Expression , Identifier , IfCondition , Line , Literal , RelationOperator ,
3- Statement , VarDeclaration ,
2+ ArithmeticOperator , BinaryExpression , Expression , Identifier , IfCondition , Line , Literal ,
3+ RelationOperator , Statement , UnaryExpression , UnaryOperator , VarDeclaration ,
44} ;
55use crate :: errors:: RuntimeError ;
66use crate :: parser:: Parser ;
@@ -14,7 +14,7 @@ use crate::io::{clear, load_file, read_line, save_file, set_prompt, write_line};
1414
1515#[ derive( Debug , Clone , PartialEq ) ]
1616enum Value {
17- Number ( usize ) ,
17+ Number ( f32 ) ,
1818 String ( String ) ,
1919 // Boolean(bool),
2020 None ,
@@ -84,52 +84,64 @@ impl Interpreter {
8484 match value {
8585 Some ( value) => Ok ( value. clone ( ) ) ,
8686 None => Err ( RuntimeError :: UndefinedVariable (
87- self . context
88- . program
89- . get ( self . context . current_line )
90- . unwrap ( )
91- . source ,
87+ format ! ( "{}" , identifier. name) . to_string ( ) ,
9288 ) ) ,
9389 }
9490 }
95- Expression :: Literal ( literal) => match literal {
96- Literal :: Number { value } => Ok ( Value :: Number ( * value) ) ,
97- Literal :: String { value } => Ok ( Value :: String ( value. clone ( ) ) ) ,
98- } ,
99- Expression :: BinaryExpression ( binary) => {
100- let left = self . visit_expression ( & binary. left ) ?;
101- let right = self . visit_expression ( & binary. right ) ?;
102-
103- match ( left, right) {
104- ( Value :: Number ( left) , Value :: Number ( right) ) => {
105- let result = match binary. operator {
106- ArithmeticOperator :: Add => left + right,
107- ArithmeticOperator :: Subtract => left - right,
108- ArithmeticOperator :: Multiply => left * right,
109- ArithmeticOperator :: Divide => left / right,
110- } ;
111-
112- Ok ( Value :: Number ( result) )
113- }
114- ( Value :: String ( left) , Value :: String ( right) ) => {
115- let result = match binary. operator {
116- ArithmeticOperator :: Add => left + & right,
117- _ => {
118- return Err ( RuntimeError :: InvalidOperation (
119- self . context . current_line ,
120- ) )
121- }
122- } ;
123-
124- Ok ( Value :: String ( result) )
125- }
91+ Expression :: Literal ( literal) => self . visit_literal ( literal) ,
92+ Expression :: UnaryExpression ( unary) => self . visit_unary_expression ( unary) ,
93+ Expression :: BinaryExpression ( binary) => self . visit_binary_expression ( binary) ,
94+ _ => return Err ( RuntimeError :: InvalidOperation ( self . context . current_line ) ) ,
95+ }
96+ }
97+
98+ fn visit_literal ( & self , literal : & Literal ) -> InterpreterResult {
99+ match literal {
100+ Literal :: Number { value } => Ok ( Value :: Number ( * value) ) ,
101+ Literal :: String { value } => Ok ( Value :: String ( value. clone ( ) ) ) ,
102+ }
103+ }
104+
105+ fn visit_binary_expression ( & self , binary : & BinaryExpression ) -> InterpreterResult {
106+ let left = self . visit_expression ( & binary. left ) ?;
107+ let right = self . visit_expression ( & binary. right ) ?;
108+
109+ match ( left, right) {
110+ ( Value :: Number ( left) , Value :: Number ( right) ) => {
111+ let result = match binary. operator {
112+ ArithmeticOperator :: Add => left + right,
113+ ArithmeticOperator :: Subtract => left - right,
114+ ArithmeticOperator :: Multiply => left * right,
115+ ArithmeticOperator :: Divide => left / right,
116+ } ;
117+
118+ Ok ( Value :: Number ( result) )
119+ }
120+ ( Value :: String ( left) , Value :: String ( right) ) => {
121+ let result = match binary. operator {
122+ ArithmeticOperator :: Add => left + & right,
126123 _ => return Err ( RuntimeError :: InvalidOperation ( self . context . current_line ) ) ,
127- }
124+ } ;
125+
126+ Ok ( Value :: String ( result) )
128127 }
129128 _ => return Err ( RuntimeError :: InvalidOperation ( self . context . current_line ) ) ,
130129 }
131130 }
132131
132+ fn visit_unary_expression ( & self , unary : & UnaryExpression ) -> InterpreterResult {
133+ let value = self . visit_expression ( & unary. argument ) ?;
134+
135+ match value {
136+ Value :: Number ( number) => match unary. operator {
137+ Some ( UnaryOperator :: Plus ) => Ok ( Value :: Number ( number) ) ,
138+ Some ( UnaryOperator :: Minus ) => Ok ( Value :: Number ( -number) ) ,
139+ None => Ok ( Value :: Number ( number) ) ,
140+ } ,
141+ _ => Err ( RuntimeError :: InvalidOperation ( self . context . current_line ) ) ,
142+ }
143+ }
144+
133145 fn visit_print_statement ( & self , expressions : & Vec < Expression > ) -> InterpreterResult {
134146 let mut results: Vec < String > = vec ! [ ] ;
135147 for expression in expressions {
@@ -247,7 +259,7 @@ impl Interpreter {
247259 value => return Err ( RuntimeError :: IllegalLineNumber ( format ! ( "{}" , value) ) ) ,
248260 } ;
249261
250- self . context . current_line = location;
262+ self . context . current_line = location as usize ;
251263
252264 Ok ( Value :: None )
253265 }
0 commit comments