From 291d5724f2f2cc24ccc753f42816f601abc440db Mon Sep 17 00:00:00 2001
From: afonya2 <adamhir@freemail.hu>
Date: Sun, 8 Jun 2025 23:06:21 +0200
Subject: [PATCH] add continous function execution and table get

---
 src/enviroment.rs     |  2 +-
 src/parser.rs         | 90 +++++++++++++++++++++++++++++++++++++------
 src/virtualmachine.rs |  2 +-
 test.as               |  7 +++-
 4 files changed, 86 insertions(+), 15 deletions(-)

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<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);
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