add continous function execution and table get

This commit is contained in:
afonya2 2025-06-08 23:06:21 +02:00
parent 1addc28463
commit 291d5724f2
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
4 changed files with 86 additions and 15 deletions

View file

@ -10,7 +10,7 @@ fn get_string_from_vmmem(mem: VMMemory) -> String {
VMMemory::Boolean(b) => out.push_str(if b.value { "true" } else { "false" }),
VMMemory::Null(_) => out.push_str("null"),
VMMemory::Table(tbl) => {
out.push_str("{ ");
out.push_str("{");
for val in &tbl.values {
out.push_str(&get_string_from_vmmem(val.key.clone()));
out.push_str("=");

View file

@ -463,7 +463,8 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
} else if token.typ == TokenType::IDENTIFIER {
if next_token.typ == TokenType::SEPARATOR && next_token.value == "(" {
let var = ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos });
expressions.push(read_call(var, pos, input, ctx));
let cal = read_call(var, pos, input, ctx);
expressions.push(check_continue(pos, input, cal, parse_ends, parse_ends, ctx));
} else if next_token.typ == TokenType::SEPARATOR && next_token.value == "[" {
let var_pos = token.pos;
let key_ends: Vec<Token> = vec![
@ -490,7 +491,8 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
process::exit(1);
}
*pos += 1;
expressions.push(ASTPart::TableGet(AstTableGet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: var_pos })), key: Box::new(keyy), pos: var_pos+1 }));
let gt = ASTPart::TableGet(AstTableGet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: var_pos })), key: Box::new(keyy), pos: var_pos+1 });
expressions.push(check_continue(pos, input, gt, parse_ends, parse_ends, ctx));
} else if next_token.typ == TokenType::SEPARATOR && next_token.value == "." {
let var_pos = token.pos;
*pos += 1;
@ -501,7 +503,8 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
process::exit(1);
}
*pos += 1;
expressions.push(ASTPart::TableGet(AstTableGet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: var_pos })), key: Box::new(ASTPart::String(AstString { value: keyy.value.clone(), pos: keyy.pos })), pos: var_pos+1 }));
let gt = ASTPart::TableGet(AstTableGet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: var_pos })), key: Box::new(ASTPart::String(AstString { value: keyy.value.clone(), pos: keyy.pos })), pos: var_pos+1 });
expressions.push(check_continue(pos, input, gt, parse_ends, parse_ends, ctx));
} else {
expressions.push(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos }));
}
@ -540,6 +543,70 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
return shunted;
}
fn check_continue(pos: &mut usize, input: &Vec<Token>, prev: ASTPart, op_ends: &Vec<Token>, parse_ends: &Vec<Token>, ctx: &Context) -> ASTPart {
let token = &input[*pos];
let mut next_token = &Token {
typ: TokenType::OPEND,
value: String::from("END"),
pos: 0
};
if *pos+1 < input.len() {
next_token = &input[*pos+1]
}
if is_end(token, &parse_ends) {
return prev;
}
if is_end(token, &op_ends) {
return prev;
}
if token.typ == TokenType::SEPARATOR && token.value == "(" {
let cal = read_call(prev, pos, input, ctx);
return check_continue(pos, input, cal, op_ends, parse_ends, ctx)
}
if token.typ == TokenType::SEPARATOR && token.value == "[" {
let var_pos = token.pos;
*pos += 1;
let key_ends: Vec<Token> = vec![
Token { typ: TokenType::SEPARATOR, value: String::from("]"), pos: 0 }
];
let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx);
match keyy {
ASTPart::Table(_) => {
let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys);
print_error(&err, &ctx);
process::exit(1);
},
ASTPart::Function(_) => {
let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys);
print_error(&err, &ctx);
process::exit(1);
},
_ => {}
}
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" {
let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd);
print_error(&err, &ctx);
process::exit(1);
}
*pos += 1;
let gt = ASTPart::TableGet(AstTableGet { table: Box::new(prev), key: Box::new(keyy), pos: var_pos+1 });
return check_continue(pos, input, gt, op_ends, parse_ends, ctx);
} else if token.typ == TokenType::SEPARATOR && token.value == "." {
let var_pos = token.pos;
*pos += 1;
let keyy = &input[*pos];
if keyy.typ != TokenType::IDENTIFIER {
let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected);
print_error(&err, &ctx);
process::exit(1);
}
*pos += 1;
let gt = ASTPart::TableGet(AstTableGet { table: Box::new(prev), key: Box::new(ASTPart::String(AstString { value: keyy.value.clone(), pos: keyy.pos })), pos: var_pos+1 });
return check_continue(pos, input, gt, op_ends, parse_ends, ctx);
}
return prev;
}
fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, parse_ends: &Vec<Token>, ctx: &Context) -> ASTPart {
let token = &input[*pos];
let mut next_token = &Token {
@ -735,7 +802,8 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
} else if token.typ == TokenType::IDENTIFIER {
if next_token.typ == TokenType::SEPARATOR && next_token.value == "(" {
let var = ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos });
return read_call(var, pos, input, ctx);
let cal = read_call(var, pos, input, ctx);
return check_continue(pos, input, cal, op_ends, parse_ends, ctx)
} else if next_token.typ == TokenType::SEPARATOR && next_token.value == "[" {
*pos += 1;
let key_ends: Vec<Token> = vec![
@ -761,14 +829,14 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
process::exit(1);
}
*pos += 1;
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "=" {
let err = create_error(&format!("Expected `=` after key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected);
print_error(&err, &ctx);
process::exit(1);
if input[*pos].typ == TokenType::SEPARATOR && input[*pos].value == "=" {
*pos += 1;
let value = read_exp(pos, input, op_ends, parse_ends, ctx);
return ASTPart::TableSet(AstTableSet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos })), key: Box::new(keyy), value: Box::new(value), pos: token.pos });
} else {
let gt = ASTPart::TableGet(AstTableGet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos })), key: Box::new(keyy.clone()), pos: token.pos });
return check_continue(pos, input, gt, op_ends, parse_ends, ctx);
}
*pos += 1;
let value = read_exp(pos, input, op_ends, parse_ends, ctx);
return ASTPart::TableSet(AstTableSet { table: Box::new(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos })), key: Box::new(keyy), value: Box::new(value), pos: token.pos });
} else if next_token.typ == TokenType::SEPARATOR && next_token.value == "=" {
*pos += 1;
let value = read_exp(pos, input, op_ends, parse_ends, ctx);

View file

@ -806,7 +806,7 @@ impl Machine {
self.stack.clear();
},
_ => {
let err = create_error(&format!("Unable to call non-function type"), 0, ErrorType::MachineError, ErrorSubType::NonFunctionCall);
let err = create_error(&format!("Unable to call non-function type"), operation.pos, ErrorType::MachineError, ErrorSubType::NonFunctionCall);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}

View file

@ -1,2 +1,5 @@
gethelj a = {[szaft"test"szaft] = 1}
ugass(a.1)
gethelj a = lőcsve() {
reti {[szaft"test"szaft]=1}
}
ugass(a().test)