A small programming language and its development

How it all started

I sat in my third year of college and did nothing, getting an A. I learned the material quickly (thanks to the forums and habr), but something was missing and then I took up the study of operating systems, hoping to do something for the diploma. Time passed, practice and the third course ended.





Moving on to the next course, I began to actively study everything related to the OS, but I really didn't get anywhere. Then the idea was born to me to create my own YaP.





There was not much time, but it was necessary to do something, and I wrote something in my free time (with a gray RFP).





I decided to call the language The Gorge.





Part one. How language works and where to find it

It was decided to place the language on the github platform and create a new profile.

At that time, I had at my disposal the old accredited account, but later I created my own and now it can be found like this: (just add the site) / pcPowerJG / natural-network.





In the src folder in the lib.rs file, we can see a miracle, the language is written almost entirely in rast (why almost? Unfortunately in the distant times of 2019, the rast did not allow opening the file in my favorite manger and had to open it through C).





Well, the first thing I needed to do was create a dictionary of used keywords.





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
      
      



As we can see, words have a certain numbering (and not from scratch. This is important ).





The next main function is the start function.





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