Fix using self within self
This commit is contained in:
		
							parent
							
								
									dc360ef196
								
							
						
					
					
						commit
						1f56fa5dc3
					
				| @ -1,5 +1,6 @@ | |||||||
| import std::print; | import std::print; | ||||||
| import std::from_str; | import std::from_str; | ||||||
|  | import std::String; | ||||||
| 
 | 
 | ||||||
| struct Otus { | struct Otus { | ||||||
|     field: u32, |     field: u32, | ||||||
|  | |||||||
| @ -1,22 +1,19 @@ | |||||||
| import std::print; | import std::print; | ||||||
| import std::from_str; | import std::from_str; | ||||||
| import std::add_char; |  | ||||||
| import std::set_char; | import std::set_char; | ||||||
| import std::free_string; | import std::free_string; | ||||||
| import std::add_num_to_str; |  | ||||||
| import std::concat_strings; |  | ||||||
| import std::String; | import std::String; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| fn main() { | 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, '!'); |     test.add_char('!'); | ||||||
|     add_char(&mut test, '\n'); |     test.add_char('\n'); | ||||||
| 
 | 
 | ||||||
|     add_num_to_str(&mut test, 175); |     test.push_num(175); | ||||||
|      |      | ||||||
|     print(test); |     print(test); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,6 +20,61 @@ impl String { | |||||||
|             must_be_freed: true, |             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 { | impl binop (lhs: String) + (rhs: *char) -> String { | ||||||
|  | |||||||
| @ -691,12 +691,23 @@ impl Parse for FunctionSignature { | |||||||
| 
 | 
 | ||||||
|             let self_kind = stream.parse::<SelfParam>().map(|s| s.0).unwrap_or(SelfKind::None); |             let self_kind = stream.parse::<SelfParam>().map(|s| s.0).unwrap_or(SelfKind::None); | ||||||
| 
 | 
 | ||||||
|             if let Ok(param) = stream.parse::<FunctionParam>() { |             match &self_kind { | ||||||
|                 params.push((param.0, param.1)); |                 SelfKind::None => { | ||||||
|                 while let Some(Token::Comma) = stream.peek() { |                     if let Ok(param) = stream.parse::<FunctionParam>() { | ||||||
|                     stream.next(); |                         params.push((param.0, param.1)); | ||||||
|                     let param = stream.parse::<FunctionParam>()?; |                         while let Some(Token::Comma) = stream.peek() { | ||||||
|                     params.push((param.0, param.1)); |                             stream.next(); | ||||||
|  |                             let param = stream.parse::<FunctionParam>()?; | ||||||
|  |                             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)); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -208,6 +208,19 @@ impl TypeKind { | |||||||
|             None |             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 { | impl BinaryOperator { | ||||||
|  | |||||||
| @ -248,7 +248,7 @@ pub struct NamedVariableRef(pub TypeKind, pub String, pub Metadata); | |||||||
| #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||||||
| pub struct Import(pub Vec<String>, pub Metadata); | pub struct Import(pub Vec<String>, pub Metadata); | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub enum ExprKind { | pub enum ExprKind { | ||||||
|     Variable(NamedVariableRef), |     Variable(NamedVariableRef), | ||||||
|     Indexed(Box<Expression>, TypeKind, Box<Expression>), |     Indexed(Box<Expression>, TypeKind, Box<Expression>), | ||||||
| @ -266,14 +266,14 @@ pub enum ExprKind { | |||||||
|     CastTo(Box<Expression>, TypeKind), |     CastTo(Box<Expression>, TypeKind), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub struct Expression(pub ExprKind, pub Metadata); | pub struct Expression(pub ExprKind, pub Metadata); | ||||||
| 
 | 
 | ||||||
| /// Condition, Then, Else
 | /// Condition, Then, Else
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub struct IfExpression(pub Box<Expression>, pub Box<Expression>, pub Box<Option<Expression>>); | pub struct IfExpression(pub Box<Expression>, pub Box<Expression>, pub Box<Option<Expression>>); | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub struct FunctionCall { | pub struct FunctionCall { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub return_type: TypeKind, |     pub return_type: TypeKind, | ||||||
| @ -328,7 +328,7 @@ impl FunctionDefinition { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub struct Block { | pub struct Block { | ||||||
|     /// List of non-returning statements
 |     /// List of non-returning statements
 | ||||||
|     pub statements: Vec<Statement>, |     pub statements: Vec<Statement>, | ||||||
| @ -336,10 +336,10 @@ pub struct Block { | |||||||
|     pub meta: Metadata, |     pub meta: Metadata, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub struct Statement(pub StmtKind, pub Metadata); | pub struct Statement(pub StmtKind, pub Metadata); | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub enum StmtKind { | pub enum StmtKind { | ||||||
|     /// Variable name++mutability+type, evaluation
 |     /// Variable name++mutability+type, evaluation
 | ||||||
|     Let(NamedVariableRef, bool, Expression), |     Let(NamedVariableRef, bool, Expression), | ||||||
| @ -349,7 +349,7 @@ pub enum StmtKind { | |||||||
|     While(WhileStatement), |     While(WhileStatement), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug, Clone)] | ||||||
| pub struct WhileStatement { | pub struct WhileStatement { | ||||||
|     pub condition: Expression, |     pub condition: Expression, | ||||||
|     pub block: Block, |     pub block: Block, | ||||||
|  | |||||||
| @ -749,7 +749,9 @@ impl Expression { | |||||||
|                         .into_iter() |                         .into_iter() | ||||||
|                         .chain(iter::repeat(TypeKind::Vague(Vague::Unknown))); |                         .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
 |                         // Typecheck every param separately
 | ||||||
|                         let param_res = param.typecheck(state, &typerefs, HintKind::Coerce(true_param_t.clone())); |                         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); |                         let param_t = state.or_else(param_res, TypeKind::Vague(Vague::Unknown), param.1); | ||||||
|  | |||||||
| @ -603,17 +603,31 @@ impl Expression { | |||||||
|                             .get_mut(0) |                             .get_mut(0) | ||||||
|                             .expect("Unknown-type associated function NEEDS to always have at least one parameter!"); |                             .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(); |                         let param_ty = first_param.infer_types(state, type_refs).unwrap().resolve_deep(); | ||||||
|                         *type_kind = state.or_else( |                         *type_kind = state | ||||||
|                             param_ty.ok_or(ErrorKind::CouldNotInferType(format!("{}", first_param))), |                             .or_else( | ||||||
|                             Void, |                                 param_ty.ok_or(ErrorKind::CouldNotInferType(format!("{}", first_param))), | ||||||
|                             first_param.1, |                                 Void, | ||||||
|                         ); |                                 first_param.1, | ||||||
|  |                             ) | ||||||
|  |                             .unroll_borrows() | ||||||
|  |                             .resolve_ref(type_refs.types); | ||||||
|                         let backing_var = first_param.backing_var().expect("todo").1.clone(); |                         let backing_var = first_param.backing_var().expect("todo").1.clone(); | ||||||
|                         dbg!(&backing_var); | 
 | ||||||
|                         dbg!(&state.scope.variables.get(&backing_var)); |                         *first_param = if backing_var == "self" { | ||||||
|                         let mutable = state.scope.variables.get(&backing_var).expect("todo").mutable; |                             let ExprKind::Borrow(val, _) = &first_param.0 else { | ||||||
|                         if !mutable { |                                 panic!() | ||||||
|                             first_param.remove_borrow_mutability(); |                             }; | ||||||
|  |                             *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