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,12 +691,23 @@ impl Parse for FunctionSignature {
|
||||
|
||||
let self_kind = stream.parse::<SelfParam>().map(|s| s.0).unwrap_or(SelfKind::None);
|
||||
|
||||
if let Ok(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));
|
||||
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() {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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,17 +603,31 @@ 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(
|
||||
param_ty.ok_or(ErrorKind::CouldNotInferType(format!("{}", first_param))),
|
||||
Void,
|
||||
first_param.1,
|
||||
);
|
||||
*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;
|
||||
if !mutable {
|
||||
first_param.remove_borrow_mutability();
|
||||
|
||||
*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