diff --git a/runtime/ast/parser.py b/runtime/ast/parser.py index 039391c..dd13cbe 100644 --- a/runtime/ast/parser.py +++ b/runtime/ast/parser.py @@ -55,7 +55,15 @@ class Parser: "body": body, } + def if_statement(self): + self.eat('if') + return { + "type": 'IfStatement', + } + def expression_statement(self): + if self.token_type() == "if": + return self.if_statement() if self.token_type() == "return": return self.return_statement() if self._is_literal(): diff --git a/runtime/ast/runtime.py b/runtime/ast/runtime.py index a000724..901f666 100644 --- a/runtime/ast/runtime.py +++ b/runtime/ast/runtime.py @@ -32,9 +32,8 @@ class Runtime: def assignment_expression(self, ast): id = ast.get("identifier").get("name") v = ast.get("value") - l = self.literal(v) - self.records[id] = self.unquote(v) - + self.set_identifier_value(id, self.unquote(v)) + def _is_call_function(self, ast): return ast["type"] == "CallExpression" @@ -44,14 +43,32 @@ class Runtime: unquoted_args = [] for arg in args: unquoted_args.append(self.unquote(arg)) - fu = self.records.get(id) + fu = self.get_identifier_value(id) if fu == None: raise Exception("Function not found: " + id) return fu(*unquoted_args) + + def get_identifier_value(self, key): + v = self.records.get(key) + if v != None: + return v + if self.parent != None: + return self.parent.get_identifier_value(key) + return None + + def set_identifier_value(self, key, value): + v = self.records.get(key) + if v != None: + self.records[key] = value + return + if self.parent != None: + self.parent.set_identifier_value(key, value) + return + raise Exception("Identifier not found: " + key) def unquote(self, ast): if self._is_identifier(ast): - return self.records.get(ast.get("name")) + return self.get_identifier_value(ast.get("name")) if self._is_literal(ast): return self.literal(ast) if self._is_call_function(ast): diff --git a/runtime/ast/tokenizer.py b/runtime/ast/tokenizer.py index 1a1467f..4071b3b 100644 --- a/runtime/ast/tokenizer.py +++ b/runtime/ast/tokenizer.py @@ -39,6 +39,15 @@ specs = ( # Assignment: (re.compile(r"^="), "SIMPLE_ASSIGN"), + # Logical operators: + (re.compile(r"^&&"), "AND"), + (re.compile(r"^\|\|"), "OR"), + (re.compile(r"^!"), "NOT"), + + # Math operators: +, -, *, /: + (re.compile(r"^[+-]"), "ADDITIVE_OPERATOR"), + (re.compile(r"^[*/]"), "MULTIPLICATIVE_OPERATOR"), + # Double-quoted strings (re.compile(r"^\"[^\"]*\""), "STRING"), diff --git a/runtime_example.py b/runtime_example.py index 427f159..b12a6f5 100644 --- a/runtime_example.py +++ b/runtime_example.py @@ -4,10 +4,9 @@ from runtime.ast.parser import Parser from runtime.ast.runtime import Runtime script = """ -let hello = true -let text = audio_to_text(audio) -print(hello) -return tts(text) +let hello = add(div(1,2),2) + +return hello """ def version(): @@ -42,10 +41,7 @@ if __name__ == "__main__": "version": version, "print": print }) + ast = Parser().parse(script) # 注入數據 - script_output = runtime.run(Parser().parse(script), { - "audio": audio_data - }) - f = open("./test_data/runtime_output.mp3", "wb") - f.write(script_output.read()) - f.close() \ No newline at end of file + script_output = runtime.run(ast, {}) + print("script:",script_output) \ No newline at end of file