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