Wie alles begann
Ich saß in meinem dritten Studienjahr und tat nichts, bekam ein A. Ich lernte das Material schnell (dank Foren und Habr), aber es fehlte etwas und dann nahm ich das Studium der Betriebssysteme auf, in der Hoffnung, etwas für das Diplom zu tun. Die Zeit verging, das Training und der dritte Kurs endeten.
Als ich zum nächsten Kurs überging, begann ich aktiv alles zu studieren, was mit dem Betriebssystem zu tun hatte, aber ich kam wirklich nicht weiter. Dann kam mir die Idee, meine eigene Programmiersprache zu erstellen.
Es gab wenig Zeit, aber es war notwendig, etwas zu tun, und ich schrieb etwas in meiner Freizeit (mit einem grauen RFP).
Ich beschloss, die Sprache The Gorge zu nennen.
Teil eins. Wie Sprache funktioniert und wo sie zu finden ist
Es wurde beschlossen, die Sprache auf der Github-Plattform zu platzieren und ein neues Profil zu erstellen.
Zu dieser Zeit hatte ich das alte Konto zur Verfügung, aber später habe ich immer noch mein eigenes erstellt und jetzt kann es so gefunden werden: (fügen Sie einfach die Site hinzu) / pcPowerJG / natural-network.
Im src-Ordner in der lib.rs-Datei können wir ein Wunder sehen, die Sprache ist fast vollständig in Rast geschrieben (warum fast? Leider erlaubte das Rast in den fernen Zeiten von 2019 nicht, die Datei in meiner Lieblingsmanagerin und zu öffnen musste es über C) öffnen.
Nun, das erste, was ich tun musste, war ein Wörterbuch mit verwendeten Schlüsselwörtern zu erstellen.
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
Wie wir sehen können, haben Wörter eine bestimmte Nummerierung (und nicht von Grund auf neu. Dies ist wichtig ).
Die nächste Hauptfunktion ist die Startfunktion.
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")
. ( ( , ), ) , . - , .
?
( , );
? ;
.