2025-02-03 23:04:36 +02:00
use std ::fmt ;
2025-02-03 16:35:06 +02:00
2025-02-04 17:07:41 +02:00
#[ derive(PartialEq, Debug, Clone) ]
2025-02-04 16:09:05 +02:00
pub enum Type {
Int ,
Bool ,
Func ( Vec < Type > , Box < Type > ) ,
Unit ,
}
2025-02-03 18:01:39 +02:00
#[ derive(PartialEq, PartialOrd, Debug, Copy, Clone) ]
2025-02-03 16:35:06 +02:00
pub enum Value {
Int ( i64 ) ,
Bool ( bool ) ,
2025-02-03 23:04:36 +02:00
Func ( fn ( & [ Value ] ) -> Value ) ,
2025-02-03 16:35:06 +02:00
None ( ) ,
}
impl fmt ::Display for Value {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
match self {
Value ::Int ( val ) = > write! ( f , " {} " , val ) ,
Value ::Bool ( val ) = > write! ( f , " {} " , val ) ,
2025-02-03 23:04:36 +02:00
Value ::Func ( _ ) = > write! ( f , " <FunctionCall> " ) ,
2025-02-03 16:35:06 +02:00
Value ::None ( ) = > write! ( f , " <Unit> " ) ,
}
}
}
2025-02-03 23:04:36 +02:00
impl Value {
pub fn add ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
let Value ::Int ( lhs ) = args [ 0 ] else {
2025-02-03 16:35:06 +02:00
panic! ( " Can't apply + to non-ints! " )
2025-02-03 23:04:36 +02:00
} ;
let Value ::Int ( rhs ) = args [ 1 ] else {
panic! ( " Can't apply + to non-ints! " )
} ;
Value ::Int ( lhs + rhs )
2025-02-03 16:35:06 +02:00
}
2025-02-03 23:04:36 +02:00
pub fn mul ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
let Value ::Int ( lhs ) = args [ 0 ] else {
2025-02-03 16:35:06 +02:00
panic! ( " Can't apply * to non-ints! " )
2025-02-03 23:04:36 +02:00
} ;
let Value ::Int ( rhs ) = args [ 1 ] else {
panic! ( " Can't apply * to non-ints! " )
} ;
Value ::Int ( lhs * rhs )
2025-02-03 16:35:06 +02:00
}
2025-02-03 23:04:36 +02:00
pub fn sub ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
let Value ::Int ( lhs ) = args [ 0 ] else {
2025-02-03 16:35:06 +02:00
panic! ( " Can't apply - to non-ints! " )
2025-02-03 23:04:36 +02:00
} ;
let Value ::Int ( rhs ) = args [ 1 ] else {
panic! ( " Can't apply - to non-ints! " )
} ;
Value ::Int ( lhs - rhs )
2025-02-03 16:35:06 +02:00
}
2025-02-03 23:04:36 +02:00
pub fn div ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
let Value ::Int ( lhs ) = args [ 0 ] else {
2025-02-03 16:35:06 +02:00
panic! ( " Can't apply / to non-ints! " )
2025-02-03 23:04:36 +02:00
} ;
let Value ::Int ( rhs ) = args [ 1 ] else {
panic! ( " Can't apply / to non-ints! " )
} ;
Value ::Int ( lhs / rhs )
2025-02-03 16:35:06 +02:00
}
2025-02-03 23:04:36 +02:00
pub fn rem ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
let Value ::Int ( lhs ) = args [ 0 ] else {
2025-02-03 16:35:06 +02:00
panic! ( " Can't apply % to non-ints! " )
2025-02-03 23:04:36 +02:00
} ;
let Value ::Int ( rhs ) = args [ 1 ] else {
panic! ( " Can't apply % to non-ints! " )
} ;
Value ::Int ( lhs / rhs )
2025-02-03 16:35:06 +02:00
}
2025-02-03 23:04:36 +02:00
pub fn eq ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
Value ::Bool ( args [ 0 ] = = args [ 1 ] )
}
2025-02-03 16:35:06 +02:00
2025-02-03 23:04:36 +02:00
pub fn neq ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
Value ::Bool ( args [ 0 ] ! = args [ 1 ] )
2025-02-03 16:35:06 +02:00
}
2025-02-03 23:04:36 +02:00
pub fn lt ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
Value ::Bool ( args [ 0 ] < args [ 1 ] )
}
2025-02-03 16:35:06 +02:00
2025-02-03 23:04:36 +02:00
pub fn le ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
Value ::Bool ( args [ 0 ] < = args [ 1 ] )
}
pub fn gt ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
Value ::Bool ( args [ 0 ] > args [ 1 ] )
}
pub fn ge ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 2 ) ;
Value ::Bool ( args [ 0 ] > = args [ 1 ] )
}
pub fn not ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 1 ) ;
let Value ::Bool ( val ) = args [ 0 ] else {
panic! ( " Can't apply 'not' to non-bools! " )
} ;
Value ::Bool ( ! val )
}
pub fn neg ( args : & [ Self ] ) -> Self {
assert_eq! ( args . len ( ) , 1 ) ;
let Value ::Int ( val ) = args [ 0 ] else {
panic! ( " Can't apply negation to non-ints! " )
} ;
Value ::Int ( - val )
2025-02-03 16:35:06 +02:00
}
}