summaryrefslogtreecommitdiff
path: root/query/parse.py
diff options
context:
space:
mode:
authorromangraef <roman.graef@gmail.com>2018-05-15 20:02:18 +0200
committerromangraef <roman.graef@gmail.com>2018-05-15 20:02:18 +0200
commit9187528a1e4d96aee5381138547c62ed7e281aa8 (patch)
tree5aaea27d46ba55d54866cacb130425cbcd560896 /query/parse.py
parent50787a7a3c14b8cbe1890cfdc62bc1d27171209c (diff)
downloadfuckingselfbot-9187528a1e4d96aee5381138547c62ed7e281aa8.tar.gz
fuckingselfbot-9187528a1e4d96aee5381138547c62ed7e281aa8.tar.bz2
fuckingselfbot-9187528a1e4d96aee5381138547c62ed7e281aa8.zip
~stream languageHEADmaster
Diffstat (limited to 'query/parse.py')
-rw-r--r--query/parse.py113
1 files changed, 113 insertions, 0 deletions
diff --git a/query/parse.py b/query/parse.py
new file mode 100644
index 0000000..b509044
--- /dev/null
+++ b/query/parse.py
@@ -0,0 +1,113 @@
+from typing import List
+
+from antlr4 import *
+
+from query.QueryLexer import QueryLexer
+from query.QueryParser import QueryParser
+from query.QueryVisitor import QueryVisitor
+
+
+def make_function(outer_scope, argument_names: List[str], parser: QueryParser, prog: QueryParser.ProgContext):
+ def function(*args):
+ visitor = MyQueryVisitor(parser)
+ visitor.memory = outer_scope.copy()
+ for i in range(len(args)):
+ visitor.memory[argument_names[i]] = args[i]
+ return visitor.for_result(prog)
+
+ return function
+
+
+class Return(Exception):
+ def __init__(self, thing):
+ self.ret = thing
+
+
+class MyQueryVisitor(QueryVisitor):
+ def __init__(self, parser: QueryParser):
+ self.memory = {
+ }
+ self.parser: QueryParser = parser
+ self.last_expr = None
+
+ def for_result(self, ctx):
+ try:
+ self.visit(ctx)
+ except Return as ret:
+ return ret.ret
+ return self.last_expr
+
+ def visitProg(self, ctx: QueryParser.ProgContext):
+ for stat in ctx.getChildren(lambda child: isinstance(child, QueryParser.StatContext)):
+ self.visit(stat)
+
+ def visitFunc(self, ctx: QueryParser.FuncContext):
+ args = ctx.arguments().getText()[:-2].split(',')
+ return make_function(self.memory, args, self.parser, ctx.prog())
+
+ def visitAssign(self, ctx):
+ name = ctx.ID().getText()
+ value = self.visit(ctx.expr())
+ self.memory[name] = value
+ return value
+
+ def visitRawExpr(self, ctx: QueryParser.RawExprContext):
+ value = self.visit(ctx.expr())
+ self.last_expr = value
+ return value
+
+ def visitInt(self, ctx):
+ return int(ctx.INT().getText())
+
+ def visitId(self, ctx):
+ name = ctx.ID().getText()
+ if name in self.memory:
+ return self.memory[name]
+ return 0
+
+ def visitAccess(self, ctx: QueryParser.AccessContext):
+ thing = self.visit(ctx.expr())
+ return getattr(thing, ctx.ID(), 0)
+
+ def visitMulDiv(self, ctx):
+ left = (self.visit(ctx.expr(0)))
+ right = (self.visit(ctx.expr(1)))
+ if ctx.op.type == QueryParser.MUL:
+ return left * right
+ return left / right
+
+ def visitString(self, ctx: QueryParser.StringContext):
+ return eval(ctx.getText())
+
+ def visitAddSub(self, ctx):
+ left = int(self.visit(ctx.expr(0)))
+ right = int(self.visit(ctx.expr(1)))
+ if ctx.op.type == QueryParser.ADD:
+ return left + right
+ return left - right
+
+ def visitParens(self, ctx):
+ return self.visit(ctx.expr())
+
+ def visitCall(self, ctx: QueryParser.CallContext):
+ to_call = self.visit(ctx.expr(0))
+ args = [self.visit(arg) for arg in ctx.getChildren(lambda x: isinstance(x, QueryParser.ExprContext))][1:]
+ return to_call(*args)
+
+ def visit(self, tree):
+ return super(MyQueryVisitor, self).visit(tree)
+
+
+def parse(text, **kwargs):
+ parser = QueryParser(CommonTokenStream(QueryLexer(InputStream(text))))
+ tree = parser.prog()
+ visitor = MyQueryVisitor(parser)
+ for key, value in kwargs.items():
+ visitor.memory[key] = value
+ return visitor.for_result(tree)
+
+
+if __name__ == '__main__':
+ with open('debug.txt') as handle:
+ content = handle.read()
+ print(parse(content))