예제 #1
0
 def visitFnGetStream(self, ctx: YalangParser.FnGetStreamContext):
     l = self.visit(ctx.left)
     if l.typ != Expression.Type.ASYNC_CALL:
         raise VisitorException(ctx, "Cannot get stream from {}", l.typ)
     ident = ctx.right.text
     s = l.ins.get(ident, None)
     if s is None:
         s = l.outs.get(ident, None)
     if s is None:
         raise VisitorException(ctx, "Cannot get stream {}", ident)
     if self.debug:
         self.debug_info.append(s)
     return s
예제 #2
0
 def visitStreamWrite(self, ctx: YalangParser.StreamWriteContext):
     s = self.visit(ctx.right)
     if s.typ != Expression.Type.STREAM:
         raise VisitorException(ctx, "Cannot write to {}", l.typ)
     if self.async_fn is None and not s.is_in():
         raise VisitorException(
             ctx, "Cannot write to output of another function")
     if self.async_fn is not None and s in self.async_fn.ins.values():
         raise VisitorException(ctx,
                                "Cannot write to input within function")
     e = self.visit(ctx.left)
     if self.debug:
         self.debug_info.append(e)
     return s.write(e)
예제 #3
0
 def visitIdentifier(self, ctx: YalangParser.IdentifierContext):
     ident = ctx.ID().getText()
     e = self.scope.get(ident, None)
     if e is None:
         raise VisitorException(ctx, "Undefined variable {}", ident)
     if self.debug:
         self.debug_info.append(e)
     return e
예제 #4
0
 def visitReturnStmt(self, ctx: YalangParser.ReturnStmtContext):
     if not self.is_fn:
         raise VisitorException(
             ctx, "Return statement is allowed only in functions")
     e = self.visit(ctx.expression())
     self.return_value = e
     if self.debug:
         self.debug_info.append(e)
     return e
예제 #5
0
 def visitFnCall(self, ctx: YalangParser.FnCallContext):
     f = self.visit(ctx.callee)
     if f.typ != Expression.Type.FUNCTION:
         raise VisitorException(ctx, "variable is not callable")
     params = [self.visit(p) for p in ctx.params]
     r = f.call(ctx, params, self.async_calls)
     if self.debug:
         self.debug_info.append(r)
     return r
예제 #6
0
 def visitUnaryMinus(self, ctx: YalangParser.UnaryMinusContext):
     expr = self.visit(ctx.expression())
     if not expr.is_number():
         raise VisitorException(ctx, "Unary Math on non-numeric value: -{}",
                                expr)
     e = Expression('-' + expr.value, expr.typ)
     if self.debug:
         self.debug_info.append(e)
     return e
예제 #7
0
 def visitStreamRead(self, ctx: YalangParser.StreamReadContext):
     s = self.visit(ctx.expression())
     if s.typ != Expression.Type.STREAM:
         raise VisitorException(ctx, "Cannot read from {}", l.typ)
     if self.async_fn is None and s.is_in():
         raise VisitorException(
             ctx, "Cannot read from input to another function")
     if self.async_fn is not None and s in self.async_fn.outs.values():
         raise VisitorException(ctx,
                                "Cannot read from output within function")
     try:
         e = s.read()
     except LoopExit as ex:
         raise VisitorException(ctx, "Deadlock detected")
     if e is None:
         raise VisitorException(ctx, "Attempted read from empty stream")
     if self.debug:
         self.debug_info.append(e)
     return e
예제 #8
0
 def visitBinaryMath(self, ctx):
     op = ctx.op.text
     l = self.visit(ctx.left)
     r = self.visit(ctx.right)
     if not l.is_number() or not r.is_number():
         raise VisitorException(
             ctx, "Binary Math on non-numeric values: {} {} {}", l.value,
             op, r.value)
     r = eval(l.value + op + r.value)
     e = Expression(str(r), l.typ)
     if self.debug:
         self.debug_info.append(e)
     return e
예제 #9
0
 def __init__(self, ctx, scope, ins, args, outs, body):
     self.ctx = ctx
     if len(set(ins) & set(outs)) > 0:
         raise VisitorException(
             ctx, "Name clash between input and output streams")
     self.scope = scope
     self.ins = ins
     self.args = args
     self.outs = outs
     self.is_async = len(ins) > 0 or len(outs) > 0
     self.body = body
     self.exception = None
     self.typ = self.Type.FUNCTION
     self.value = None
예제 #10
0
    def call(self, call_ctx, params, async_calls):
        if len(params) != len(self.args):
            raise VisitorException(call_ctx,
                                   "function requires {} args, {} given",
                                   len(self.args), len(params))

        scope = self.scope.copy()
        for k, v in zip(self.args, params):
            scope[k] = v

        if self.is_async:
            ac = AsyncCall(scope, self.ins, self.outs, self.body)
            ac.start(async_calls)
            return ac
        else:
            return call_fn(scope, self.body, async_calls=async_calls)
예제 #11
0
 def visitCloseStmt(self, ctx: YalangParser.CloseStmtContext):
     s = self.visit(ctx.stream)
     if s.typ != Expression.Type.STREAM:
         raise VisitorException(ctx, "Cannot close {}", s.typ)
     s.write(EOS)