Un peque帽o lenguaje de programaci贸n y su desarrollo.

C贸mo empez贸 todo

Me sent茅 en mi tercer a帽o de universidad y no hice nada, obteniendo una A. Aprend铆 el material r谩pidamente (gracias a foros y habr), pero faltaba algo y luego me dediqu茅 al estudio de los sistemas operativos, con la esperanza de hacer algo por el diploma. Pas贸 el tiempo, practic贸 y termin贸 el tercer curso.





Pasando al siguiente curso, comenc茅 a estudiar activamente todo lo relacionado con el sistema operativo, pero realmente no llegu茅 a ninguna parte. Entonces me naci贸 la idea de crear mi propio lenguaje de programaci贸n.





Hab铆a poco tiempo, pero era necesario hacer algo, y escrib铆 algo en mi tiempo libre (con una RFP gris).





Decid铆 llamar al idioma The Gorge.





Parte uno. C贸mo funciona el idioma y d贸nde encontrarlo

Se decidi贸 colocar el idioma en la plataforma github y crear un nuevo perfil.

En ese momento, ten铆a a mi disposici贸n la cuenta anterior que me dieron, pero luego cre茅 la m铆a propia y ahora se puede encontrar as铆: (solo agregue el sitio) / pcPowerJG / natural-network.





En la carpeta src en el archivo lib.rs, podemos ver un milagro, el lenguaje est谩 escrito casi en su totalidad en rast (驴por qu茅 casi? Desafortunadamente en los tiempos lejanos de 2019, el rast no permiti贸 abrir el archivo en mi pesebre favorito y Tuve que abrirlo a trav茅s de C).





Bueno, lo primero que ten铆a que hacer era crear un diccionario de palabras clave 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, las palabras tienen cierta numeraci贸n (y no parten de cero. Esto es importante ).





La siguiente funci贸n principal es la funci贸n de inicio.





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