Fix using self within self
This commit is contained in:
		
							parent
							
								
									dc360ef196
								
							
						
					
					
						commit
						1f56fa5dc3
					
				| @ -1,5 +1,6 @@ | ||||
| import std::print; | ||||
| import std::from_str; | ||||
| import std::String; | ||||
| 
 | ||||
| struct Otus { | ||||
|     field: u32, | ||||
|  | ||||
| @ -1,22 +1,19 @@ | ||||
| import std::print; | ||||
| import std::from_str; | ||||
| import std::add_char; | ||||
| import std::set_char; | ||||
| import std::free_string; | ||||
| import std::add_num_to_str; | ||||
| import std::concat_strings; | ||||
| import std::String; | ||||
| 
 | ||||
| 
 | ||||
| fn main() { | ||||
|     let mut test = String::new(); | ||||
|     let mut test = String::from("hello"); | ||||
| 
 | ||||
|     concat_strings(&mut test, from_str(" world")); | ||||
|     test.push(String::from(" world")); | ||||
| 
 | ||||
|     add_char(&mut test, '!'); | ||||
|     add_char(&mut test, '\n'); | ||||
|     test.add_char('!'); | ||||
|     test.add_char('\n'); | ||||
| 
 | ||||
|     add_num_to_str(&mut test, 175); | ||||
|     test.push_num(175); | ||||
|      | ||||
|     print(test); | ||||
| 
 | ||||
|  | ||||
| @ -20,6 +20,61 @@ impl String { | ||||
|             must_be_freed: true, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn from(str: *char) -> String { | ||||
|         let length = str_length(str) as u64; | ||||
|         let mut new = String::new(); | ||||
|         let static = String { | ||||
|             inner: str, | ||||
|             length: length - 1, | ||||
|             max_length: length, | ||||
|             must_be_freed: false, | ||||
|         }; | ||||
|         concat_strings(&mut new, static); | ||||
|         return new; | ||||
|     } | ||||
| 
 | ||||
|     pub fn push(&mut self, other: String) { | ||||
|         for i in 0 .. (str_length(other.inner) - 1) { | ||||
|             add_char(self, other.inner[i]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_char(&mut self, c: char) { | ||||
|         if ((*self).length + 1) >= (*self).max_length { | ||||
|             let new = allocate((*self).max_length + 4) as *char; | ||||
|             copy_bits((*self).inner, new, (*self).max_length); | ||||
| 
 | ||||
|             if (*self).must_be_freed == true { | ||||
|                 free((*self).inner as *u8); | ||||
|             } | ||||
|             (*self).max_length = (*self).max_length + 4; | ||||
|             (*self).inner = new; | ||||
|             (*self).must_be_freed = true; | ||||
|         } | ||||
| 
 | ||||
|         (*self).inner[(*self).length] = c; | ||||
|         (((*self).inner) as *u8)[(*self).length + 1] = 0; | ||||
|         (*self).length = (*self).length + 1; | ||||
|     } | ||||
| 
 | ||||
|     pub fn push_num(&mut self, num: u64) { | ||||
|         if num >= 10 { | ||||
|             self.push_num(num / 10) | ||||
|         } | ||||
|         let rem = num % 10; | ||||
| 
 | ||||
|         if rem == 0 { self.add_char('0'); }  | ||||
|         else if rem == 1 { self.add_char('1'); } | ||||
|         else if rem == 2 { self.add_char('2'); } | ||||
|         else if rem == 3 { self.add_char('3'); } | ||||
|         else if rem == 4 { self.add_char('4'); } | ||||
|         else if rem == 5 { self.add_char('5'); } | ||||
|         else if rem == 6 { self.add_char('6'); } | ||||
|         else if rem == 7 { self.add_char('7'); } | ||||
|         else if rem == 8 { self.add_char('8'); } | ||||
|         else if rem == 9 { self.add_char('9'); } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl binop (lhs: String) + (rhs: *char) -> String { | ||||
|  | ||||
| @ -691,6 +691,8 @@ impl Parse for FunctionSignature { | ||||
| 
 | ||||
|             let self_kind = stream.parse::<SelfParam>().map(|s| s.0).unwrap_or(SelfKind::None); | ||||
| 
 | ||||
|             match &self_kind { | ||||
|                 SelfKind::None => { | ||||
|                     if let Ok(param) = stream.parse::<FunctionParam>() { | ||||
|                         params.push((param.0, param.1)); | ||||
|                         while let Some(Token::Comma) = stream.peek() { | ||||
| @ -699,6 +701,15 @@ impl Parse for FunctionSignature { | ||||
|                             params.push((param.0, param.1)); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 _ => { | ||||
|                     while let Some(Token::Comma) = stream.peek() { | ||||
|                         stream.next(); | ||||
|                         let param = stream.parse::<FunctionParam>()?; | ||||
|                         params.push((param.0, param.1)); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             stream.expect(Token::ParenClose)?; | ||||
| 
 | ||||
|  | ||||
| @ -208,6 +208,19 @@ impl TypeKind { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn unroll_borrows(&self) -> TypeKind { | ||||
|         match self { | ||||
|             TypeKind::Borrow(type_kind, mut1) => match *type_kind.clone() { | ||||
|                 TypeKind::Borrow(type_kind, mut2) => match (mut1, mut2) { | ||||
|                     (false, false) => TypeKind::Borrow(Box::new(*type_kind.clone()), false), | ||||
|                     _ => TypeKind::Borrow(Box::new(*type_kind.clone()), true), | ||||
|                 }, | ||||
|                 _ => self.clone(), | ||||
|             }, | ||||
|             _ => self.clone(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl BinaryOperator { | ||||
|  | ||||
| @ -248,7 +248,7 @@ pub struct NamedVariableRef(pub TypeKind, pub String, pub Metadata); | ||||
| #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||||
| pub struct Import(pub Vec<String>, pub Metadata); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ExprKind { | ||||
|     Variable(NamedVariableRef), | ||||
|     Indexed(Box<Expression>, TypeKind, Box<Expression>), | ||||
| @ -266,14 +266,14 @@ pub enum ExprKind { | ||||
|     CastTo(Box<Expression>, TypeKind), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Expression(pub ExprKind, pub Metadata); | ||||
| 
 | ||||
| /// Condition, Then, Else
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct IfExpression(pub Box<Expression>, pub Box<Expression>, pub Box<Option<Expression>>); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FunctionCall { | ||||
|     pub name: String, | ||||
|     pub return_type: TypeKind, | ||||
| @ -328,7 +328,7 @@ impl FunctionDefinition { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Block { | ||||
|     /// List of non-returning statements
 | ||||
|     pub statements: Vec<Statement>, | ||||
| @ -336,10 +336,10 @@ pub struct Block { | ||||
|     pub meta: Metadata, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Statement(pub StmtKind, pub Metadata); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum StmtKind { | ||||
|     /// Variable name++mutability+type, evaluation
 | ||||
|     Let(NamedVariableRef, bool, Expression), | ||||
| @ -349,7 +349,7 @@ pub enum StmtKind { | ||||
|     While(WhileStatement), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct WhileStatement { | ||||
|     pub condition: Expression, | ||||
|     pub block: Block, | ||||
|  | ||||
| @ -749,7 +749,9 @@ impl Expression { | ||||
|                         .into_iter() | ||||
|                         .chain(iter::repeat(TypeKind::Vague(Vague::Unknown))); | ||||
| 
 | ||||
|                     for (param, true_param_t) in function_call.parameters.iter_mut().zip(true_params_iter) { | ||||
|                     for (i, (param, true_param_t)) in | ||||
|                         function_call.parameters.iter_mut().zip(true_params_iter).enumerate() | ||||
|                     { | ||||
|                         // Typecheck every param separately
 | ||||
|                         let param_res = param.typecheck(state, &typerefs, HintKind::Coerce(true_param_t.clone())); | ||||
|                         let param_t = state.or_else(param_res, TypeKind::Vague(Vague::Unknown), param.1); | ||||
|  | ||||
| @ -603,18 +603,32 @@ impl Expression { | ||||
|                             .get_mut(0) | ||||
|                             .expect("Unknown-type associated function NEEDS to always have at least one parameter!"); | ||||
|                         let param_ty = first_param.infer_types(state, type_refs).unwrap().resolve_deep(); | ||||
|                         *type_kind = state.or_else( | ||||
|                         *type_kind = state | ||||
|                             .or_else( | ||||
|                                 param_ty.ok_or(ErrorKind::CouldNotInferType(format!("{}", first_param))), | ||||
|                                 Void, | ||||
|                                 first_param.1, | ||||
|                         ); | ||||
|                             ) | ||||
|                             .unroll_borrows() | ||||
|                             .resolve_ref(type_refs.types); | ||||
|                         let backing_var = first_param.backing_var().expect("todo").1.clone(); | ||||
|                         dbg!(&backing_var); | ||||
|                         dbg!(&state.scope.variables.get(&backing_var)); | ||||
|                         let mutable = state.scope.variables.get(&backing_var).expect("todo").mutable; | ||||
| 
 | ||||
|                         *first_param = if backing_var == "self" { | ||||
|                             let ExprKind::Borrow(val, _) = &first_param.0 else { | ||||
|                                 panic!() | ||||
|                             }; | ||||
|                             *val.clone() | ||||
|                         } else { | ||||
|                             first_param.clone() | ||||
|                         }; | ||||
| 
 | ||||
|                         if let Some((mutable, _)) = type_refs.find_var(&backing_var) { | ||||
|                             if !mutable { | ||||
|                                 first_param.remove_borrow_mutability(); | ||||
|                             } | ||||
|                         } else { | ||||
|                             return Err(ErrorKind::VariableNotDefined(backing_var)); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user