Example #1
0
 def gencode(self, env, opt):
     if self.body:
         codes = self.body.gencode(env, newopt(opt, 1)).bytecodes
     else:
         codes = [m.Inst(opc.PUSH, 0)]
     codes.append(m.Inst(opc.RET, self.nullarg))
     return m.Insts(m.Type(), codes)
Example #2
0
class Funccall(AST):
    def __init__(self, tok, name, args):
        self.tok = tok
        self.name = name
        self.args = args

    def gencode(self, env, opt):

        if (result := self.assertOnlyRValue(env, opt)) is not None:
            return result

        try:
            define = env.functionLookup(self.name)
        except m.SymbolNotFoundException:
            g.r.addReport(
                m.Report('error', self.tok,
                         f"function '{self.name}' not defined"))
            return m.Insts()

        if self.args is None:
            self.args = []

        selfArgLength = len(self.args)
        definedArgLength = len(define.args)

        if selfArgLength != definedArgLength:
            g.r.addReport(
                m.Report(
                    'error', self.tok,
                    f'too {"many" if selfArgLength > definedArgLength else "few"} arguments to function call, expected {definedArgLength}, have {selfArgLength}'
                ))
            return m.Insts()

        mytype = define.typ
        codes = []
        argtypes = []
        for elem in reversed(self.args):
            arg = elem.gencode(env, newopt(opt, 1))
            codes.extend(arg.bytecodes)
            argtypes.append(arg.typ)

        argtypes = list(reversed(argtypes))

        for i in range(selfArgLength):
            if argtypes[i] != define.args[i].typ:
                g.r.addReport(
                    m.Report(
                        'error', self.tok,
                        f'{"%d%s" % (i+1,"tsnrhtdd"[(i+1//10%10!=1)*((i+1)%10<4)*(i+1)%10::4])} parameter type mismatches'
                    ))
                return m.Insts()

        codes.append(m.Inst(opc.CALL, self.name))
        codes.append(m.Inst(opc.POPR, len(self.args)))
        if (opt.popc == 0):
            codes.append(m.Inst(opc.POP, self.nullarg))

        env.markCalledFunc(self.name)

        return m.Insts(mytype, codes)
Example #3
0
class Post_dec(AST):
    def __init__(self, tok, left):
        self.tok = tok
        self.left = left

    def gencode(self, env, opt):

        if (result := self.assertOnlyRValue(env, opt)) is not None:
            return result

        left = self.left.gencode(env, newopt(opt, 1, 'r'))
        codes = left.bytecodes
        typ = copy(left.typ)

        if (opt.popc == 1):
            codes.append(m.Inst(opc.DUP, self.nullarg))
        else:
            typ = m.Type()

        if typ.isPointer():
            codes.append(m.Inst(opc.DEC, env.calcPointeredSize(typ)))
        else:
            codes.append(m.Inst(opc.DEC, 1))

        codes.extend(self.left.gencode(env, newopt(opt, 0, 'l')).bytecodes)

        return m.Insts(typ, codes)
Example #4
0
    def gencode(self, env, opt):
        cond = self.cond.gencode(env, newopt(opt, 1)).bytecodes
        then = self.then.gencode(env, newopt(opt, 0)).bytecodes

        l0 = env.issueLabel()
        codes = cond
        codes.append(m.Inst(opc.JIF0, l0))
        codes.extend(then)
        codes.append(m.Inst(opc.LABEL, l0))
        return m.Insts(m.Type(), codes)
Example #5
0
    def gencode(self, env, opt):
        left = self.left.gencode(env, newopt(opt, 1))
        codes = left.bytecodes

        field = env.getField(left.typ, self.fieldname)  # TODO handle exception
        #            g.r.addReport(m.Report('error', self.tok, f"cannot get field '{self.fieldname}' of type '{left.typ}'"))
        #            return m.Insts()
        codes.append(m.Inst(opc.PUSH, field[0]))
        codes.append(m.Inst(opc.ADDI, self.nullarg))

        return m.Insts(field[1], codes)
Example #6
0
    def gencode(self, env, opt):

        l0 = env.issueLabel()

        body = self.body.gencode(env, newopt(opt, cp=l0, bp=None)).bytecodes
        cond = self.cond.gencode(env, newopt(opt, 1)).bytecodes

        codes = [m.Inst(opc.LABEL, l0)]
        codes.extend(body)
        codes.extend(cond)
        codes.append(m.Inst(opc.INV, self.nullarg))
        codes.append(m.Inst(opc.JIF0, l0))

        return m.Insts(m.Type(), codes)
Example #7
0
 def gencode(self, env, opt):
     if opt.bp is None:
         g.r.addReport(
             m.Report('error', self.tok, 'break in unbreakable point'))
         return m.Insts()
     else:
         return m.Insts(m.Type(), [m.Inst(opc.JUMP, opt.bp)])
Example #8
0
    def gencode(self, env, opt):
        label = env.currentFuncName + self.name
        expr = self.expr.gencode(env, newopt(opt, 0))

        codes = [m.Inst(opc.LABEL, label)]
        codes.extend(expr.bytecodes)

        return m.Insts(expr.typ, codes)
Example #9
0
    def gencode(self, env, opt):
        #        self.typ.resolve(env)
        insts = []
        for elem in reversed(self.bodys):
            insts.extend(elem.gencode(env, newopt(opt, 1)).bytecodes)
        #insts.append(m.Inst(opc[self.opc], self.arg.eval()))
        insts.append(m.Inst(opc[self.opc], self.arg))

        return m.Insts(self.typ, insts)
Example #10
0
    def gencode(self, env, opt):

        body = self.body.gencode(env, newopt(opt, 1))
        codes = body.bytecodes
        if opt.lr == 'r':
            if (result := self.assertOnlyPop1(env, opt)) is not None:
                return result
            codes.append(m.Inst(opc.LOADP, self.nullarg))
            return m.Insts(copy(body.typ).addRefcount(-1), codes)
Example #11
0
    def gencode(self, env, opt):
        cond = self.cond.gencode(env, newopt(opt, 1))
        then = self.then.gencode(env, newopt(opt, 1))
        elst = self.elst.gencode(env, newopt(opt, 1))

        # TODO check if then.typ != elst.typ

        l0 = env.issueLabel()
        l1 = env.issueLabel()

        codes = cond.bytecodes
        codes.append(m.Inst(opc.JIF0, l0))
        codes.extend(then.bytecodes)
        codes.append(m.Inst(opc.JUMP, l1))
        codes.append(m.Inst(opc.LABEL, l0))
        codes.extend(elst.bytecodes)
        codes.append(m.Inst(opc.LABEL, l1))

        return m.Insts(then.typ, codes)
Example #12
0
 def gencode(self, env, opt):
     if opt.cp is None:
         g.r.addReport(
             m.Report(
                 'error', self.tok,
                 'to continue, you need extra gem! (you can\'t continue here.)'
             ))
         return m.Insts()
     else:
         return m.Insts(m.Type(), [m.Inst(opc.JUMP, opt.cp)])
Example #13
0
class Cast(AST):
    def __init__(self, tok, targetType, body):
        self.tok = tok
        self.targetType = targetType
        self.body = body

    def gencode(self, env, opt):

        if (result := self.assertOnlyPop1(env, opt)) is not None:
            return result

        bodyc = self.body.gencode(env, newopt(opt, 1))
        codes = bodyc.bytecodes

        if bodyc.typ.basetype == 'int':
            if self.targetType.basetype == 'float':
                codes.append(m.Inst(opc.ITOF, self.nullarg))
                return m.Insts(m.Type('float'), codes)
            else:
                g.r.addReport(
                    m.Report(
                        'fatal', self.tok,
                        'Program error occurred while evaluating \'Cast\' #0'))
                return m.Insts()

        elif bodyc.typ.basetype == 'float':
            if self.targetType.basetype == 'int':
                codes.append(m.Inst(opc.FTOI, self.nullarg))
                return m.Insts(m.Type('int'), codes)
            else:
                g.r.addReport(
                    m.Report(
                        'fatal', self.tok,
                        'Program error occurred while evaluating \'Cast\' #1'))
                return m.Insts()

        else:
            g.r.addReport(
                m.Report(
                    'fatal', self.tok,
                    'Program error occurred while evaluating \'Cast\' #2'))
            return m.Insts()
Example #14
0
    def gencode(self, env, opt):
        if isinstance(self.body, m.Type):
            return m.Insts(m.Type('int'),
                           [m.Inst(opc.PUSH, env.calcTypeSize(self.body))])
        elif isinstance(self.body, Symbol):
            try:
                var = env.variableLookup(self.body.symbolname)
            except m.SymbolNotFoundException as e:
                g.r.addReport(
                    m.Report('fatal', self.tok,
                             f"cannot eval size of type '{type(self.body)}'"))
                return m.Insts()

            return m.Insts(m.Type('int'),
                           [m.Inst(opc.PUSH, env.calcTypeSize(var.typ))])
        else:
            g.r.addReport(
                m.Report('fatal', self.tok,
                         f"cannot eval size of type '{type(self.body)}'"))
        return m.Insts()
Example #15
0
    def gencode(self, env, opt):

        try:
            env.addFunction(
                m.Function(self.symbolname, self.typ, self.args, None))
        except m.SymbolRedefineException:
            g.r.addReport(
                m.Report('error', self.tok,
                         f"Redefinition of '{self.symbolname}'"))

        if self.body is None:  # 定義
            return env

        env.resetFrame(self.symbolname)

        for elem in self.args:
            env.addArg(elem)

        codes = self.body.gencode(env, newopt(opt, 0)).bytecodes

        insts = []
        insts.append(m.Inst(opc.ENTRY, self.symbolname))
        insts.append(m.Inst(opc.FRAME, env.getFrameSize()))
        insts.extend(codes)
        if (insts[-1].opc is not opc.RET):
            insts.append(m.Inst(opc.PUSH, 0))
            insts.append(m.Inst(opc.RET, self.nullarg))

        try:
            env.addFunction(
                m.Function(self.symbolname, self.typ, self.args, insts))
        except m.SymbolRedefineException:
            g.r.addReport(
                m.Report('error', self.tok,
                         f"Redefinition of '{self.symbolname}'"))
        except m.ConflictingTypesException:
            g.r.addReport(
                m.Report('error', self.tok,
                         f"Conflicting types for '{self.symbolname}'"))

        return env
Example #16
0
    def gencode(self, env, opt):

        env.calcTypeSize(self.typ, self.init)
        var = env.addLocal(m.Symbol(self.symbolname, self.typ))

        if self.init is None:
            return m.Insts()
        elif isinstance(self.init, list):
            codes = []
            for i, elem in enumerate(self.init):
                codes.extend(elem.gencode(env, newopt(opt, 1)).bytecodes)
                codes.append(var.genAddrCode())
                codes.append(m.Inst(opc.PUSH, i))
                codes.append(m.Inst(opc.ADDI, self.nullarg))
                codes.append(m.Inst(opc.STOREP, self.nullarg))
            return m.Insts(m.Type(), codes)
        else:
            codes = self.init.gencode(env, newopt(opt, 1)).bytecodes
            codes.append(m.Inst(opc.STOREL, var.id))

        return m.Insts(m.Type(), codes)
Example #17
0
    def gencode(self, env, opt):

        l0 = env.issueLabel()
        l1 = env.issueLabel()

        if self.init is None:  # TODO 1ライン化するか関数化して全部に適用
            init = []
        else:
            init = self.init.gencode(env, newopt(opt, 0)).bytecodes
        cond = self.cond.gencode(env, newopt(opt, 1)).bytecodes
        loop = self.loop.gencode(env, newopt(opt, 0)).bytecodes
        body = self.body.gencode(env, newopt(opt, 0, cp=l0, bp=l1)).bytecodes

        codes = init
        codes.append(m.Inst(opc.LABEL, l0))
        codes.extend(cond)
        codes.append(m.Inst(opc.JIF0, l1))
        codes.extend(body)
        codes.extend(loop)
        codes.append(m.Inst(opc.JUMP, l0))
        codes.append(m.Inst(opc.LABEL, l1))
        return m.Insts(m.Type(), codes)
Example #18
0
    def gencode(self, env, opt):

        right = self.right.gencode(env, newopt(opt, 1))
        left = self.left.gencode(env, newopt(opt, 1, 'l'))

        typ = m.Type()

        codes = right.bytecodes
        if opt.popc == 1:
            codes.append(m.Inst(opc.DUP, 1))
            typ = right.typ
        codes.extend(left.bytecodes)

        return m.Insts(typ, codes)
Example #19
0
    def gencode(self, env, opt):

        tableCodes = self.cond.gencode(env, newopt(opt, 1)).bytecodes
        bodyCodes = []
        end = env.issueLabel()
        default = None

        for elem in self.cases:
            label = env.issueLabel()
            if elem[0] == 'default':
                default = label
                bodyCodes.append(m.Inst(opc.LABEL, label))
                for e in elem[1]:
                    bodyCodes.extend(
                        e.gencode(env, newopt(opt, 1, bp=end)).bytecodes)
            else:
                tableCodes.append(m.Inst(opc.DUP, 1))
                tableCodes.extend(elem[0].gencode(env, newopt(opt,
                                                              1)).bytecodes)
                tableCodes.append(m.Inst(opc.NEQI,
                                         self.nullarg))  #TODO Int以外にも対応させる
                tableCodes.append(m.Inst(opc.JIF0, label))

                bodyCodes.append(m.Inst(opc.LABEL, label))
                for e in elem[1]:
                    bodyCodes.extend(
                        e.gencode(env, newopt(opt, 1, bp=end)).bytecodes)

        if default is not None:
            tableCodes.append(m.Inst(opc.JUMP, default))
        else:
            tableCodes.append(m.Inst(opc.JUMP, end))

        bodyCodes.append(m.Inst(opc.LABEL, end))
        bodyCodes.append(m.Inst(opc.POP, self.nullarg))

        codes = tableCodes
        codes.extend(bodyCodes)

        return m.Insts(m.Type(), codes)
Example #20
0
class Symbol(AST):
    def __init__(self, tok, symbolname):
        self.tok = tok
        self.symbolname = symbolname

    def gencode(self, env, opt):

        try:
            var = env.variableLookup(self.symbolname)
        except m.SymbolNotFoundException as e:

            # 変数が見つからなかったら、Enumとして解決を試みる
            try:
                value = env.enumLookup(self.symbolname)
            except m.SymbolNotFoundException as e:
                g.r.addReport(m.Report('error', self.tok, f'{e} not found'))
                return m.Insts()

            if (result := self.assertOnlyRValue(env, opt)) is not None:
                return result
            if (result := self.assertOnlyPop1(env, opt)) is not None:
                return result

            return m.Insts(m.Type('int'), [m.Inst(opc.PUSH, value)])
Example #21
0
    def gencode(self, env, opt):

        if (result := self.assertOnlyRValue(env, opt)) is not None:
            return result
        if (result := self.assertOnlyPop1(env, opt)) is not None:
            return result

        left = self.left.gencode(env, newopt(opt, 1))
        right = self.right.gencode(env, newopt(opt, 1))

        code = right.bytecodes
        code.extend(left.bytecodes)

        if self.isCompOP:  # 比較演算子ならポインタ同士の演算が可能
            if left.typ.isPointer() or right.typ.isPointer():
                code.append(m.Inst(self.opI, self.nullarg))
                return m.Insts(m.Type('int'), code)
        else:  # そうでないならスカラーしか演算できない
            if not (left.typ.isScalar() and right.typ.isScalar()):
                g.r.addReport(
                    m.Report(
                        'error', self.tok,
                        f"invalid operands to binary expression('{left.typ}' and '{right.typ}')"
                    ))
                return m.Insts()

        if (not left.typ.isBasetype()):
            left.typ = env.getType(left.typ.basetype)

        if (not right.typ.isBasetype()):
            right.typ = env.getType(right.typ.basetype)
Example #22
0
 def gencode(self, env, opt):
     label = env.currentFuncName + self.name
     return m.Insts(m.Type(), [m.Inst(opc.JUMP, label)])