diff --git a/src/enviroment.rs b/src/enviroment.rs index b06ff45..0dcd7ff 100644 --- a/src/enviroment.rs +++ b/src/enviroment.rs @@ -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("="); diff --git a/src/parser.rs b/src/parser.rs index f2b105a..13ef6d2 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -463,7 +463,8 @@ fn read_exp(pos: &mut usize, input: &Vec, ends: &Vec, 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 = vec![ @@ -490,7 +491,8 @@ fn read_exp(pos: &mut usize, input: &Vec, ends: &Vec, 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, ends: &Vec, 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, ends: &Vec, parse_ends: return shunted; } +fn check_continue(pos: &mut usize, input: &Vec, prev: ASTPart, op_ends: &Vec, parse_ends: &Vec, 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 = 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, op_ends: &Vec, parse_ends: &Vec, ctx: &Context) -> ASTPart { let token = &input[*pos]; let mut next_token = &Token { @@ -735,7 +802,8 @@ fn next_operation(pos: &mut usize, input: &Vec, op_ends: &Vec, 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 = vec![ @@ -761,14 +829,14 @@ fn next_operation(pos: &mut usize, input: &Vec, op_ends: &Vec, 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); diff --git a/src/virtualmachine.rs b/src/virtualmachine.rs index 6de7e10..6ecf5f0 100644 --- a/src/virtualmachine.rs +++ b/src/virtualmachine.rs @@ -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); } diff --git a/test.as b/test.as index 904cade..32877a9 100644 --- a/test.as +++ b/test.as @@ -1,2 +1,5 @@ -gethelj a = {[szaft"test"szaft] = 1} -ugass(a.1) \ No newline at end of file +gethelj a = lőcsve() { + reti {[szaft"test"szaft]=1} +} + +ugass(a().test) \ No newline at end of file