Como tudo começou
Eu sentei no meu terceiro ano de faculdade e não fiz nada, tirando um A. Aprendi o material rapidamente (graças aos fóruns e habr), mas faltava alguma coisa e então retomei o estudo de sistemas operacionais, na esperança de fazer algo pelo diploma. O tempo passou, a prática e o terceiro curso terminou.
Passando para o próximo curso, comecei a estudar ativamente tudo relacionado ao sistema operacional, mas realmente não cheguei a lugar nenhum. Então, surgiu a ideia de criar minha própria linguagem de programação.
Havia pouco tempo, mas era necessário fazer algo, e escrevi algo no meu tempo livre (com um RFP cinza).
Decidi chamar a linguagem de The Gorge.
Parte um. Como a linguagem funciona e onde encontrá-la
Decidiu-se colocar o idioma na plataforma github e criar um novo perfil.
Naquela época, eu tinha à minha disposição a conta antiga que me foi dada, mas depois ainda criei a minha própria e agora ela pode ser encontrada assim: (basta adicionar o site) / pcPowerJG / natural-network.
Na pasta src do arquivo lib.rs, podemos ver um milagre, a linguagem é escrita quase inteiramente em rast (por que quase? Infelizmente em tempos distantes de 2019, o rast não permitia abrir o arquivo na minha manjedoura favorita e teve que abri-lo via C).
Bem, a primeira coisa que precisei fazer foi criar um dicionário de palavras-chave usadas.
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
Como podemos ver, as palavras têm uma certa numeração (e não do zero. Isso é importante ).
A próxima função principal é a função de início.
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")
. ( ( , ), ) , . - , .
?
( , );
? ;
.