Uma pequena linguagem de programação e seu desenvolvimento

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")
      
      



. ( ( , ), ) , . - , .





?





  1. ( , );





  2. ? ;









.








All Articles