@@ -5,10 +5,10 @@ use std::collections::HashMap;
5
5
use std:: env;
6
6
use std:: fs:: { self , File } ;
7
7
use std:: io:: { self , Error , Read , Write } ;
8
- use sys_info:: { cpu_num, cpu_speed, os_release} ;
9
8
use std:: path:: Path ;
10
9
use std:: thread:: { self , sleep} ;
11
10
use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
11
+ use sys_info:: { cpu_num, cpu_speed, hostname, mem_info, os_release, os_type} ;
12
12
13
13
#[ cfg( test) ]
14
14
mod test;
@@ -91,6 +91,7 @@ enum Type {
91
91
String ( String ) ,
92
92
Bool ( bool ) ,
93
93
List ( Vec < Type > ) ,
94
+ Object ( String , HashMap < String , Type > ) ,
94
95
Error ( String ) ,
95
96
}
96
97
@@ -103,10 +104,13 @@ impl Type {
103
104
Type :: String ( s) => format ! ( "({})" , s) ,
104
105
Type :: Bool ( b) => b. to_string ( ) ,
105
106
Type :: List ( list) => {
106
- let syntax : Vec < String > = list. iter ( ) . map ( |token| token. display ( ) ) . collect ( ) ;
107
- format ! ( "[{}]" , syntax . join( " " ) )
107
+ let result : Vec < String > = list. iter ( ) . map ( |token| token. display ( ) ) . collect ( ) ;
108
+ format ! ( "[{}]" , result . join( " " ) )
108
109
}
109
110
Type :: Error ( err) => format ! ( "error:{err}" ) ,
111
+ Type :: Object ( name, _) => {
112
+ format ! ( "Object<{name}>" )
113
+ }
110
114
}
111
115
}
112
116
@@ -118,6 +122,9 @@ impl Type {
118
122
Type :: Bool ( b) => b. to_string ( ) ,
119
123
Type :: List ( l) => Type :: List ( l. to_owned ( ) ) . display ( ) ,
120
124
Type :: Error ( err) => format ! ( "error:{err}" ) ,
125
+ Type :: Object ( name, _) => {
126
+ format ! ( "Object<{name}>" )
127
+ }
121
128
}
122
129
}
123
130
@@ -135,6 +142,7 @@ impl Type {
135
142
}
136
143
Type :: List ( l) => l. len ( ) as f64 ,
137
144
Type :: Error ( e) => e. parse ( ) . unwrap_or ( 0f64 ) ,
145
+ Type :: Object ( _, object) => object. len ( ) as f64 ,
138
146
}
139
147
}
140
148
@@ -146,6 +154,7 @@ impl Type {
146
154
Type :: Bool ( b) => * b,
147
155
Type :: List ( l) => !l. is_empty ( ) ,
148
156
Type :: Error ( e) => e. parse ( ) . unwrap_or ( false ) ,
157
+ Type :: Object ( _, object) => object. is_empty ( ) ,
149
158
}
150
159
}
151
160
@@ -161,6 +170,7 @@ impl Type {
161
170
Type :: Bool ( b) => vec ! [ Type :: Bool ( * b) ] ,
162
171
Type :: List ( l) => l. to_vec ( ) ,
163
172
Type :: Error ( e) => vec ! [ Type :: Error ( e. to_string( ) ) ] ,
173
+ Type :: Object ( _, object) => object. values ( ) . map ( |x| x. to_owned ( ) ) . collect :: < Vec < Type > > ( ) ,
164
174
}
165
175
}
166
176
}
@@ -279,7 +289,7 @@ impl Executor {
279
289
280
290
for token in syntax {
281
291
// Show inside stack to debug
282
- let stack = self . show_stack ( ) ;
292
+ let stack = self . show_stack ( ) ;
283
293
self . log_print ( format ! ( "{stack} ← {token}\n " ) ) ;
284
294
285
295
// Character vector for token processing
@@ -918,13 +928,14 @@ impl Executor {
918
928
// Get data type of value
919
929
"type" => {
920
930
let result = match self . pop_stack ( ) {
921
- Type :: Number ( _) => "number" ,
922
- Type :: String ( _) => "string" ,
923
- Type :: Bool ( _) => "bool" ,
924
- Type :: List ( _) => "list" ,
925
- Type :: Error ( _) => "error" ,
926
- }
927
- . to_string ( ) ;
931
+ Type :: Number ( _) => "number" . to_string ( ) ,
932
+ Type :: String ( _) => "string" . to_string ( ) ,
933
+ Type :: Bool ( _) => "bool" . to_string ( ) ,
934
+ Type :: List ( _) => "list" . to_string ( ) ,
935
+ Type :: Error ( _) => "error" . to_string ( ) ,
936
+ Type :: Object ( name, _) => name. to_string ( ) ,
937
+ } ;
938
+
928
939
self . stack . push ( Type :: String ( result) ) ;
929
940
}
930
941
@@ -994,7 +1005,91 @@ impl Executor {
994
1005
// Sleep fixed time
995
1006
"sleep" => sleep ( Duration :: from_secs_f64 ( self . pop_stack ( ) . get_number ( ) ) ) ,
996
1007
997
- // Command of external cooperation processing
1008
+ // Commands of object oriented system
1009
+
1010
+ // Generate a instance of object
1011
+ "instance" => {
1012
+ let data = self . pop_stack ( ) . get_list ( ) ;
1013
+ let mut methods = self . pop_stack ( ) . get_list ( ) ;
1014
+ let mut class = self . pop_stack ( ) . get_list ( ) ;
1015
+ let mut object: HashMap < String , Type > = HashMap :: new ( ) ;
1016
+ let name = class[ 0 ] . get_string ( ) ;
1017
+
1018
+ for ( name, element) in & mut class. to_owned ( ) [ 1 ..class. len ( ) ] . iter ( ) . zip ( data) {
1019
+ object. insert ( name. to_owned ( ) . get_string ( ) , element) ;
1020
+ }
1021
+
1022
+ for item in & mut methods {
1023
+ let item = item. get_list ( ) ;
1024
+ object. insert ( item[ 0 ] . clone ( ) . get_string ( ) , item[ 1 ] . clone ( ) ) ;
1025
+ }
1026
+
1027
+ self . stack . push ( Type :: Object ( name, object) )
1028
+ }
1029
+
1030
+ // Get property of object
1031
+ "property" => {
1032
+ let name = self . pop_stack ( ) . get_string ( ) ;
1033
+ match self . pop_stack ( ) {
1034
+ Type :: Object ( _, data) => self . stack . push (
1035
+ data. get ( name. as_str ( ) )
1036
+ . unwrap_or ( & Type :: Error ( "property" . to_string ( ) ) )
1037
+ . clone ( ) ,
1038
+ ) ,
1039
+ _ => self . stack . push ( Type :: Error ( "not-object" . to_string ( ) ) ) ,
1040
+ }
1041
+ }
1042
+
1043
+ // Call the method of object
1044
+ "method" => {
1045
+ let method = self . pop_stack ( ) . get_string ( ) ;
1046
+ match self . pop_stack ( ) {
1047
+ Type :: Object ( name, value) => {
1048
+ let data = Type :: Object ( name, value. clone ( ) ) ;
1049
+ self . memory
1050
+ . entry ( "self" . to_string ( ) )
1051
+ . and_modify ( |value| * value = data. clone ( ) )
1052
+ . or_insert ( data) ;
1053
+
1054
+ let program: String = match value. get ( & method) {
1055
+ Some ( i) => i. to_owned ( ) . get_string ( ) . to_string ( ) ,
1056
+ None => "" . to_string ( ) ,
1057
+ } ;
1058
+
1059
+ self . evaluate_program ( program)
1060
+ }
1061
+ _ => self . stack . push ( Type :: Error ( "not-object" . to_string ( ) ) ) ,
1062
+ }
1063
+ }
1064
+
1065
+ // Modify the property of object
1066
+ "modify" => {
1067
+ let data = self . pop_stack ( ) ;
1068
+ let property = self . pop_stack ( ) . get_string ( ) ;
1069
+ match self . pop_stack ( ) {
1070
+ Type :: Object ( name, mut value) => {
1071
+ value
1072
+ . entry ( property)
1073
+ . and_modify ( |value| * value = data. clone ( ) )
1074
+ . or_insert ( data. clone ( ) ) ;
1075
+
1076
+ self . stack . push ( Type :: Object ( name, value) )
1077
+ }
1078
+ _ => self . stack . push ( Type :: Error ( "not-object" . to_string ( ) ) ) ,
1079
+ }
1080
+ }
1081
+
1082
+ // Get all of properties
1083
+ "all" => match self . pop_stack ( ) {
1084
+ Type :: Object ( _, data) => self . stack . push ( Type :: List (
1085
+ data. keys ( )
1086
+ . map ( |x| Type :: String ( x. to_owned ( ) ) )
1087
+ . collect :: < Vec < Type > > ( ) ,
1088
+ ) ) ,
1089
+ _ => self . stack . push ( Type :: Error ( "not-object" . to_string ( ) ) ) ,
1090
+ } ,
1091
+
1092
+ // Commands of external cooperation processing
998
1093
999
1094
// Send the http request
1000
1095
"request" => {
@@ -1076,6 +1171,29 @@ impl Executor {
1076
1171
}
1077
1172
}
1078
1173
1174
+ // Copy the item
1175
+ "cp" => {
1176
+ let to = self . pop_stack ( ) . get_string ( ) ;
1177
+ let from = self . pop_stack ( ) . get_string ( ) ;
1178
+
1179
+ match fs:: copy ( from, to) {
1180
+ Ok ( i) => self . stack . push ( Type :: Number ( i as f64 ) ) ,
1181
+ Err ( e) => {
1182
+ self . log_print ( format ! ( "Error! {e}\n " ) ) ;
1183
+ self . stack . push ( Type :: Error ( "cp" . to_string ( ) ) )
1184
+ }
1185
+ }
1186
+ }
1187
+
1188
+ // Get size of the file
1189
+ "size-file" => match fs:: metadata ( self . pop_stack ( ) . get_string ( ) ) {
1190
+ Ok ( i) => self . stack . push ( Type :: Number ( i. len ( ) as f64 ) ) ,
1191
+ Err ( e) => {
1192
+ self . log_print ( format ! ( "Error! {e}\n " ) ) ;
1193
+ self . stack . push ( Type :: Error ( "size-file" . to_string ( ) ) )
1194
+ }
1195
+ } ,
1196
+
1079
1197
// Get list of files
1080
1198
"ls" => {
1081
1199
if let Ok ( entries) = fs:: read_dir ( "." ) {
@@ -1100,12 +1218,22 @@ impl Executor {
1100
1218
1101
1219
// Get system information
1102
1220
"sys-info" => {
1103
- let types = self . pop_stack ( ) . get_string ( ) ;
1104
- self . stack . push ( match types . as_str ( ) {
1221
+ let option = self . pop_stack ( ) . get_string ( ) ;
1222
+ self . stack . push ( match option . as_str ( ) {
1105
1223
"os-release" => Type :: String ( os_release ( ) . unwrap_or ( "" . to_string ( ) ) ) ,
1224
+ "os-type" => Type :: String ( os_type ( ) . unwrap_or ( "" . to_string ( ) ) ) ,
1106
1225
"cpu-num" => Type :: Number ( cpu_num ( ) . unwrap_or ( 0 ) as f64 ) ,
1107
1226
"cpu-speed" => Type :: Number ( cpu_speed ( ) . unwrap_or ( 0 ) as f64 ) ,
1108
- _ => Type :: Error ( "sys-info" . to_string ( ) )
1227
+ "host-name" => Type :: String ( hostname ( ) . unwrap_or ( "" . to_string ( ) ) ) ,
1228
+ "mem-size" => match mem_info ( ) {
1229
+ Ok ( info) => Type :: Number ( info. total as f64 ) ,
1230
+ Err ( _) => Type :: Error ( "sys-info" . to_string ( ) ) ,
1231
+ } ,
1232
+ "mem-used" => match mem_info ( ) {
1233
+ Ok ( info) => Type :: Number ( ( info. total - info. free ) as f64 ) ,
1234
+ Err ( _) => Type :: Error ( "sys-info" . to_string ( ) ) ,
1235
+ } ,
1236
+ _ => Type :: Error ( "sys-info" . to_string ( ) ) ,
1109
1237
} )
1110
1238
}
1111
1239
0 commit comments