Comment tout a commencé
J'ai passé ma troisième année à l'université et je n'ai rien fait, obtenant un A. J'ai appris le matériel rapidement (grâce aux forums et habr), mais il manquait quelque chose et ensuite j'ai commencé l'étude des systèmes d'exploitation, espérant faire quelque chose pour le diplôme. Le temps passa, la pratique et le troisième cours se terminèrent.
Passant au cours suivant, j'ai commencé à étudier activement tout ce qui concerne le système d'exploitation, mais je ne suis vraiment allé nulle part. Puis l'idée m'est venue de créer mon propre langage de programmation.
Il y avait peu de temps, mais il fallait faire quelque chose, et j'ai écrit quelque chose pendant mon temps libre (avec un appel d'offres gris).
J'ai décidé d'appeler la langue The Gorge.
Partie un. Comment fonctionne la langue et où la trouver
Il a été décidé de placer la langue sur la plateforme github et de créer un nouveau profil.
A cette époque, j'avais à ma disposition l'ancien compte qui m'était donné, mais plus tard j'ai toujours créé le mien et maintenant il peut être trouvé comme ceci: (il suffit d'ajouter le site) / pcPowerJG / natural-network.
Dans le dossier src du fichier lib.rs, on peut voir un miracle, le langage est écrit presque entièrement en rast (pourquoi presque? Malheureusement dans les temps lointains de 2019, le rast ne permettait pas d'ouvrir le fichier dans ma crèche préférée et dû l'ouvrir via C).
Eh bien, la première chose que je devais faire était de créer un dictionnaire des mots-clés utilisés.
words.push("object".to_string());//1 // ,
words.push("if".to_string());//2 // ,
words.push("exit_()".to_string());//3//
words.push("func".to_string()); //4//
words.push("print".to_string());//5 //
words.push("remove".to_string());//6 //
words.push("array".to_string());//7 //
words.push("struct".to_string()); //8 //
words.push("end".to_string());//9//end operation
words.push("end_func".to_string()); // 10 //
words.push("return".to_string()); // 11
words.push("!eq".to_string());// 12
words.push(">".to_string()); // 13
words.push("<".to_string()); // 14
words.push("loop".to_string());// 15
words.push("end_loop".to_string());// 16
words.push("_".to_string()); // 17 //
words.push("break".to_string()); // 18
words.push("true".to_string()); // 19
words.push("false".to_string()); // 20
Comme on peut le voir, les mots ont une certaine numérotation (et pas de zéro. C'est important ).
La fonction principale suivante est la fonction de démarrage.
pub fn start_(&mut self, text: String) -> u8
. , .
, - , , .
( , ..).
.
let mut temp_values: String = String::new(); //
let mut temp_name: String = String::new(); // ...
let mut temp_buffer: String = String::new(); // ...
let mut func_text: String = String::new();
let mut last_op: [usize; 3] = [0; 3]; //
// ----------------------------------------------
let mut if_count: usize = 0;
let mut if_result: bool = true; //
let mut struct_flag: bool = false; //
let mut function_inactive_flag: bool = false; //
let mut loop_flag: bool = false; //
let mut index_loop: usize = 0; // ( )
, - .
if ch == ' ' || ch == '\t' {
//...................
} else if ch == '\n' {
//...................
} else if ch == '=' {
//...................
}
} else {
temp_values.push(ch);
}
( ). , . .
else .
, .
if function_inactive_flag {
// ...
}
if loop_flag {
// ...
}
match temp_values.trim() {
// ...
}
. , ( ).
, .
.
.
: a = b + c
: last_op[0] = 1 last_op[1] = 17
: math_work .
:
fn math_work(&self, text: String) -> String {
let text: String = Words::trim(text.clone());
let mut result_string: String = String::new();
let mut temp_string: String = String::new();
for ch in text.chars() {
match ch {
'+' | '-' | '/' | '*' | '(' | ')' | '&' | '|' | '!' | '=' | '<' | '>' => {
if Words::is_digit(temp_string.clone()) {
result_string += temp_string.clone().as_str();
} else {
result_string += self.search_var(temp_string).0.clone().as_str();
}
result_string.push(ch.clone());
temp_string = String::new();
},
_ => {
temp_string.push(ch.clone());
},
}
}
let (value, type_, _temp) = self.search_var(temp_string.clone());
if _temp {
result_string += value.as_str();
} else {
result_string += temp_string.clone().as_str();
} result_string
}
, ( ) - , ( , ) .
:
fn eval(str_: Vec<char>) -> f32 {
let mut i: usize = 0;
Words::expr(str_, &mut i)
}
fn eval(str_: Vec<char>) -> f32 {
let mut i: usize = 0;
Words::expr(str_, &mut i)
}
fn plus_one(u: &mut usize) {
*u += 1;
}
fn number(ch_: Vec<char>, idx: &mut usize) -> f32 {
let mut result: f32 = 0.0;
//float result = 0.0;
let mut div: f32 = 10.0;
let mut sign: f32 = 1.0;
if ch_[*idx] == '-'{
sign = -1.0;
*idx += 1;
}
while *idx < ch_.len() &&
match ch_[*idx] {
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => { true },
_ => { false }
}
{
result = result * 10.0 + (f32::from_str(&ch_[*idx].to_string()).expect(" "));
*idx += 1;
}
if *idx < ch_.len() && (ch_[*idx] == '.'){
*idx += 1;
while *idx < ch_.len() &&
match ch_[*idx] {
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => { true },
_ => { false }
}
{
result = result + (f32::from_str(&ch_[*idx].to_string()).expect(" ")) / div;
div *= 10.0;
*idx += 1;
}
}
sign * result
}
fn expr(ch_: Vec<char>, idx: &mut usize) -> f32 {
let mut result: f32 = Words::term(ch_.clone(), idx);
while *idx < ch_.len() && (ch_[*idx] == '+' || ch_[*idx] == '-') {
match ch_[*idx] {
'+' => {
*idx += 1;
result += Words::term(ch_.clone(), idx);
},
'-' => {
*idx += 1;
result -= Words::term(ch_.clone(), idx);
},
_ => {},
}
} result
}
fn term(ch_: Vec<char>, idx: &mut usize) -> f32 {
let mut result: f32 = Words::factor(ch_.clone(), idx);
let mut div: f32 = 0.0;
while *idx < ch_.len() && (ch_[*idx] == '*' || ch_[*idx] == '/') {
match ch_[*idx] {
'*' => {
*idx += 1;
result *= Words::factor(ch_.clone(), idx);
},
'/' => {
*idx += 1;
div = Words::factor(ch_.clone(), idx);
if (div != 0.0) {
result /= div;
} else {
panic!("Division by zero!\n");
}
},
_ => {},
}
} result
}
fn factor(ch_: Vec<char>, idx: &mut usize) -> f32 {
let mut result: f32 = 0.0;
let mut sign: f32 = 1.0;
if (ch_[*idx] == '-') {
sign = -1.0;
*idx += 1;
}
if (ch_[*idx] == '(') {
*idx += 1;
result = Words::expr(ch_.clone(), idx);
if (ch_[*idx] != ')') {
panic!("Brackets unbalanced!\n");
}
*idx += 1;
} else { result = Words::number(ch_, idx); }
sign * result
}
. , .
, :
object_buffer: Vec<(String, usize)>
:
value_buffer: Vec<String>
add_vars:
fn add_vars(&mut self, vars_name: String, mut vars_value: String, vars_type: usize) {
//object_buffer: Vec<(String, usize)>
//value_buffer: Vec<String>
if vars_value.clone().split('\"').collect::<Vec<&str>>().len() > 1 {
vars_value = vars_value.split('\"').collect::<Vec<&str>>()[1].to_string();
} else {
vars_value = vars_value.clone().trim().to_string();
}
self.object_buffer.push((vars_name, vars_type));
self.value_buffer.push(vars_value);
}
, ( ).
:
fn remove_vars(&mut self, vars_name: String) {
for i in 0..self.object_buffer.len() {
if self.object_buffer[i].0.clone() == vars_name {
self.object_buffer.remove(i);
self.value_buffer.remove(i);
return;
}
}
}
:
fn set_value(&mut self, vars_name: String, mut vars_value: String) {
for i in 0..self.object_buffer.len() {
if self.object_buffer[i].0 == vars_name {
if vars_value.clone().split('\"').collect::<Vec<&str>>().len() > 1 {
vars_value = vars_value.split('\"').collect::<Vec<&str>>()[1].to_string();
} else {
vars_value = vars_value.clone().trim().to_string();
}
self.value_buffer[i] = vars_value.clone();
return;
}
}
}
pub fn search_var(&self, vars_name: String) -> (String, usize, bool) {
for i in 0..self.object_buffer.len() {
if self.object_buffer[i].0 == vars_name {
let value: String = self.value_buffer[i].clone();
let type_: usize = self.object_buffer[i].1.clone();
return (value, type_, true);
}
}
(String::new(), 0, false)
}
.
import("/lib.so")
extern_func("lib.so", func_name)
extern_func("lib.so", func_name, arg1, arg2)
close_import("lib.so")
. ( ( , ), ) , . - , .
?
( , );
? ;
.