コード例 #1
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def List(env: Env, t, out):
    ty = ts.Type()
    out.append('[')
    for sub in t:
        ty = check(ty, env, sub, out, '全ての要素を同じ型に揃えてください')
        out.append(',')
    out.append(']')
    return ts.Type(f'list[{ty}]')
コード例 #2
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def ApplyExpr(env: Env, t, out):
    name = str(t['name'])
    if name in env:
        vari = env[name]
        name = vari.target
        types = vari.types
        if name == 'world':
            set_World(env, t, types[-1])
            return ts.Matter
    elif t['name'].tag == 'NLPSymbol':
        name, types = checkNLPMatter(env, name, t)
    else:
        perror(env, t['name'], f'タイプミス? {name} 未定義な関数名です')
        return ts.Type()  # To avoid error

    if ts.isMatterFunc(types):
        with Env(env) as env:
            out.append(f'puppy.new_(puppy.vars["{name}"],')
            args = [x for x in t]
            emitArguments(env, t['name'], args, types, '', out)
            env['@@yield'] = trace(env, t)
            env['@@oid'] += 1
    else:
        out.append(name)
        out.append('(')
        args = [x for x in t]
        emitArguments(env, t['name'], args, types, '', out)
        if name == 'puppy.print':
            env['@@yield'] = trace(env, t)
            env['@@oid'] += 1
    return types[0]
コード例 #3
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def VarDecl(env: Env, t, out):
    left = t['left']
    newvar = None
    ty = None
    if left.tag == 'Name':
        name = str(left)
        if name in env:
            vari = env[name]
            ty = vari.types
            out.append(vari.target)
        elif '@local' in env:  # ローカルスコープなら
            newvar = localName(name)
            out.append(f'var {newvar}')
        else:
            newvar = globalName(name)
            out.append(newvar)
    else:
        ty = conv(env, t['left'], out)
    out.append(' = ')
    # 左辺値から型推論する
    if ty is None:
        ty = ts.Type()
    ty = check(ty, env, t['right'], out)
    if newvar != None:
        env[name] = Symbol(newvar, mutable, ty)
    return ts.Void
コード例 #4
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def conv(env: Env, t, out):
    if t.tag in func:
        return func[t.tag](env, t, out)
    else:
        perror(env, t, f'未実装のコード{t.tag}です。')
        print('@Debug[conv]', str(t), t)
        out.append('undefined')
        return ts.Type()
コード例 #5
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def Name(env: Env, t, out):
    name = str(t)
    if name in env:
        var = env[name]
        out.append(var.target)
        return var.types
    else:
        out.append(name)
        perror(env, t, f'変数名 {name} は一度も定義されていません')
        return ts.Type()
コード例 #6
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def FuncExpr(env: Env, t, out):
    with Env(env) as lenv:
        types = [ts.Type()]
        voidCheck = str(types[0])
        out.append("(")
        for p in t['params']:
            pname = str(p)
            ty = ts.Type()
            if (len(types) > 1):
                out.append(f',{pname}')
            else:
                out.append(pname)
            types.append(ty)
            lenv[pname] = Symbol(localName(pname), mutable, ty)
        out.append(") => ")
        lenv['@local'] = types[0]  # return type
        conv(lenv, t['body'], out)
        if voidCheck == str(types[0]):
            types[0] = ts.Void
    return tuple(types)
コード例 #7
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def GetExpr(env: Env, t, out):
    name = str(t['name'])
    pkgname = str(t['recv']) + '.'
    if pkgname in env:  # math.pi のような定数
        penv = env[pkgname]
        if name in penv:
            vari = penv[name]
            out.append(vari.target)
            return vari.types
        else:
            perror(env, t['name'], f'{pkgname}{name}? タイプミスしてませんか?')
            out.append('undefined')
            return ts.Type()
    check(ts.Matter, env, t['recv'], out)
    out.append('.')
    if not name in KEYWORDS:
        pwarn(env, t['name'], f'{name}? タイプミスしてませんか?')
        out.append(name)
        return ts.Type()
    else:
        name = KEYWORDS[name]
        out.append(name)
        return ts.newType(KEYWORDTYPES[name])
コード例 #8
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def FuncDecl(env: Env, t, out):
    name = str(t['name'])
    jsname = emitDeclName(env, name, out)
    with Env(env) as lenv:
        types = [ts.Type()]
        voidCheck = str(types[0])
        out.append('(')
        for p in t['params']:
            pname = str(p['name'])
            if (len(types) > 1):
                out.append(f',{pname}')
            else:
                out.append(pname)
            ty = ts.parseOf(p['type'], pwarn) if 'type' in p else ts.Type()
            types.append(ty)
            lenv[pname] = Symbol(localName(pname), mutable, ty)
        out.append(") => ")
        lenv['@local'] = types[0]  # return type
        env[name] = Symbol(jsname, mutable, tuple(types))
        conv(lenv, t['body'], out)
        if voidCheck == str(types[0]):
            types[0] = ts.Void
    return ts.Void
コード例 #9
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def ForStmt(env: Env, t, out):
    if (t['each'].tag == 'Name'):
        name = str(t['each'])
    else:
        perror(env, t['each'], '変数名が欲しいところです')
        return ts.Void
    out.append(f'for (let {name} of ')
    ty = check(ts.Type('list[__]'),
               env,
               t['list'],
               out,
               msg='ここはリストでなければなりません')
    out.append(')')
    ty = ts.typeOfSeq(ty)
    with Env(env) as env:
        env[name] = Symbol(localName(name), True, ty)
        env['inloop'] = True
        conv(env, t['body'], out)
    return ts.Void
コード例 #10
0
def ForStmt(env, t, out):
    if (t['each'].tag == 'Name'):
        name = t['each'].asString()
    else:
        perror(env, t['each'], '変数名が欲しいところです')
        return ts.Void
    out.append(f'for (let {name} of ')
    ty = check(ts.Type('list[__]'),
               env,
               t['list'],
               out,
               msg='ここはリストでなければなりません')
    out.append(')')
    ty = ts.typeOfSeq(ty)
    outer = pushenv(env, name, Symbol(localName(name), True, ty))
    outer2 = pushenv(env, '@inloop', True)
    conv(env, t['body'], out)
    popenv(env, name, outer)
    popenv(env, '@inloop', outer2)
    return ts.Void
コード例 #11
0
ファイル: puppy.py プロジェクト: y-akinobu/puppy
def emitUndefined(env: Env, t, out):
    out.append('undefined')
    return ts.Type()