コード例 #1
0
def generateBuiltinFuncs():
    builtin_functions = OrderedDict()
    for f_id, f_list in BUILTIN_FUNCTIONS.items():
        builtin_functions[(FunUniq.FUNC, f_id)] = []

        for typesig_str, _ in f_list:
            vals = typesig_str.split()
            if vals[0] == '->':
                from_types = []
                to_type = abstractToConcreteType((vals[1]))
            else:
                from_types = abstractToConcreteType(vals[0])
                to_type = abstractToConcreteType(vals[2])

            builtin_functions[(FunUniq.FUNC, f_id)].append({
                'type':
                AST.FUNTYPE(from_types=[] if len(from_types) == 0 else
                            [AST.TYPE(val=from_types[0])],
                            to_type=AST.TYPE(val=to_type[0])),
                'module':
                BUILTINS_NAME,
                'orig_id':
                f_id,
                'fixity':
                None,
                'kind':
                FunKind.FUNC
            })

    return builtin_functions
コード例 #2
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtIfElse():
    yield ps.token(TOKEN.IF)
    yield ps.token(TOKEN.PAR_OPEN)
    condition = yield Exp
    yield ps.token(TOKEN.PAR_CLOSE)
    yield ps.token(TOKEN.CURL_OPEN)
    if_contents = yield ps.many(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    first_cond = AST.CONDBRANCH(expr=condition, stmts=if_contents)

    elifs = yield ps.many(StmtElif)
    elses = yield ps.times(StmtElse, 0, 1)
    return AST.IFELSE(condbranches=[first_cond, *elifs, *elses])
コード例 #3
0
def abstractToConcreteType(abstract_type):
    if abstract_type == 'T':
        return [
            AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, b))
            for b in BASIC_TYPES
        ]
    elif abstract_type in BASIC_TYPES:
        return [
            AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER,
                                        abstract_type))
        ]
    elif abstract_type == '[T]':
        return [
            AST.LISTTYPE(type=AST.TYPE(val=AST.BASICTYPE(
                type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, b))))
            for b in BASIC_TYPES
        ]
    elif abstract_type in ['[' + x + ']' for x in BASIC_TYPES]:
        return [
            AST.LISTTYPE(type=AST.TYPE(val=AST.BASICTYPE(type_id=Token(
                Position(), TOKEN.TYPE_IDENTIFIER, abstract_type[1:-1]))))
        ]
    elif abstract_type in VOID_TYPE:
        return [Token(Position(), TOKEN.TYPE_IDENTIFIER, "Void")]
    else:
        raise Exception(
            "Unknown abstract type encountered in builtin operator table: %s" %
            abstract_type)
コード例 #4
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def FunCall():
    fname = yield ps.token(TOKEN.IDENTIFIER)
    yield ps.token(TOKEN.PAR_OPEN)
    found_args = yield ps.times(ActArgs, 0, 1)
    found_args = found_args[0] if len(found_args) > 0 else []
    yield ps.token(TOKEN.PAR_CLOSE)
    return AST.FUNCALL(id=fname, kind=FunKind.FUNC, args=found_args)
コード例 #5
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def TupType():
    yield ps.token(TOKEN.PAR_OPEN)
    el1 = yield Type
    yield ps.token(TOKEN.COMMA)
    el2 = yield Type
    yield ps.token(TOKEN.PAR_CLOSE)
    return AST.TUPLETYPE(a=el1, b=el2)
コード例 #6
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def InfixOpDecl():
    side = yield (ps.token(TOKEN.INFIXL) ^ ps.token(TOKEN.INFIXR))
    if side.typ is TOKEN.INFIXL:
        found_kind = FunKind.INFIXL
    elif side.typ is TOKEN.INFIXR:
        found_kind = FunKind.INFIXR
    else:
        raise Exception("Should never happen")
    found_fixity = yield ps.token(TOKEN.INT)
    operator = yield ps.token(TOKEN.OP_IDENTIFIER)
    yield ps.token(TOKEN.PAR_OPEN)
    a = yield ps.token(TOKEN.IDENTIFIER)
    yield ps.token(TOKEN.COMMA)
    b = yield ps.token(TOKEN.IDENTIFIER)
    yield ps.token(TOKEN.PAR_CLOSE)
    typesig = yield ps.times(InfFunTypeSig, 0, 1)
    typesig = typesig[0] if len(typesig) > 0 else None
    yield ps.token(TOKEN.CURL_OPEN)
    decls = yield ps.many(VarDecl)
    found_stmts = yield ps.many1(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    return AST.FUNDECL(kind=found_kind,
                       fixity=found_fixity,
                       id=operator,
                       params=[a, b],
                       type=typesig,
                       vardecls=decls,
                       stmts=found_stmts)
コード例 #7
0
ファイル: typechecker.py プロジェクト: W-M-T/gsc
def typecheck_stmts(func, symbol_table, ext_table):
    for vardecl in func['def'].vardecls:
        _, vardecl.expr = typecheck(vardecl.expr, vardecl.type.val, symbol_table, ext_table, func)

    stmts = list(reversed(func['def'].stmts))
    ast_boolnode = AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, "Bool"))
    while len(stmts) > 0:
        stmt = stmts.pop()
        if type(stmt.val) == AST.ACTSTMT:
            typecheck_actstmt(stmt.val, symbol_table, ext_table, func)
        elif type(stmt.val) == AST.IFELSE:
            for b in stmt.val.condbranches:
                if b.expr is not None:
                    _, b.expr = typecheck(b.expr, ast_boolnode, symbol_table, ext_table, func)
                stmts.extend(list(reversed(b.stmts)))
        elif type(stmt.val) == AST.LOOP:
            if stmt.val.cond is not None:
                _, stmt.val.cond = typecheck(stmt.val.cond, ast_boolnode, symbol_table, ext_table, func)
            if stmt.val.init is not None:
                typecheck_actstmt(stmt.val.init, symbol_table, ext_table, func)
            if stmt.val.update is not None:
                typecheck_actstmt(stmt.val.update, symbol_table, ext_table, func)
            stmts.extend(list(reversed(stmt.val.stmts)))
        elif type(stmt.val) == AST.RETURN:
            if stmt.val.expr is not None:
                _, stmt.val.expr = typecheck(stmt.val.expr, func['type'].to_type.val, symbol_table, ext_table, func)
コード例 #8
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def ExpSubTup():
    yield ps.token(TOKEN.PAR_OPEN)
    a = yield Exp
    b = yield ExpClose
    if b is None:
        return a
    else:
        return AST.TUPLE(a=a, b=b)
コード例 #9
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtElif():
    yield ps.token(TOKEN.ELIF)
    yield ps.token(TOKEN.PAR_OPEN)
    condition = yield Exp
    yield ps.token(TOKEN.PAR_CLOSE)
    yield ps.token(TOKEN.CURL_OPEN)
    contents = yield ps.many(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    return AST.CONDBRANCH(expr=condition, stmts=contents)
コード例 #10
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def VarDecl():
    typ = yield (ps.token(TOKEN.VAR) | Type)
    typ = None if type(typ) == Token and typ.typ == TOKEN.VAR else typ
    #print(typ)
    varname = yield ps.token(TOKEN.IDENTIFIER)
    yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "="))
    found_expr = yield Exp
    yield ps.token(TOKEN.SEMICOLON)
    return AST.VARDECL(type=typ, id=varname, expr=found_expr)
コード例 #11
0
def generateBuiltinTypesyns():
    temp = OrderedDict()
    for name, def_str in HIGHER_BUILTIN_TYPES.items():
        temp[(name, BUILTINS_NAME)] = OrderedDict([
            ('def_type', AST.TYPE(val=abstractToConcreteType(def_str)[0])),
            ('orig_id', name), ('decl', None)
        ])

    return temp
コード例 #12
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtWhile():
    yield ps.token(TOKEN.WHILE)
    yield ps.token(TOKEN.PAR_OPEN)
    condition = yield Exp
    yield ps.token(TOKEN.PAR_CLOSE)
    yield ps.token(TOKEN.CURL_OPEN)
    contents = yield ps.many(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)

    return AST.LOOP(init=None, cond=condition, update=None, stmts=contents)
コード例 #13
0
def mergeCustomOps(op_table, symbol_table, module_name):
    for x in symbol_table.functions:
        f = symbol_table.functions[x]
        if x[0] is FunUniq.INFIX:
            if x[1] not in op_table['infix_ops']:
                op_table['infix_ops'][x[1]] = (f[0]['def'].fixity.val,
                                               f[0]['def'].kind, [])

            for o in f:
                if op_table['infix_ops'][x[1]][0] == o[
                        'def'].fixity.val and op_table['infix_ops'][
                            x[1]][1] == o['def'].kind:
                    ft = AST.FUNTYPE(from_types=[
                        o['type'].from_types[0].val,
                        o['type'].from_types[1].val
                    ],
                                     to_type=o['type'].to_type.val)
                    cnt = 0
                    for ot in op_table['infix_ops'][x[1]][2]:
                        if AST.equalVals(ft, ot):
                            cnt += 1

                    if cnt == 0:
                        op_table['infix_ops'][x[1]][2].append(
                            (ft, module_name))
                    else:
                        ERROR_HANDLER.addError(ERR.DuplicateOpDef,
                                               [o['def'].id.val, o['def'].id])
                else:
                    ERROR_HANDLER.addError(ERR.InconsistentOpDecl,
                                           [o['def'].id.val, o['def'].id])

        elif x[0] is FunUniq.PREFIX:
            if x[1] not in op_table['prefix_ops']:
                op_table['prefix_ops'][x[1]] = []

            for o in f:
                op_table['prefix_ops'][x[1]].append(
                    (AST.FUNTYPE(from_types=[o['type'].from_types[0].val],
                                 to_type=o['type'].to_type.val), module_name))
コード例 #14
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def FunDecl():
    fname = yield ps.token(TOKEN.IDENTIFIER)
    yield ps.token(TOKEN.PAR_OPEN)
    args = yield ps.times(FArgs, 0, 1)
    args = args[0] if len(args) > 0 else args
    yield ps.token(TOKEN.PAR_CLOSE)
    typesig = yield ps.times(FunTypeSig, 0, 1)
    typesig = typesig[0] if len(typesig) > 0 else None
    yield ps.token(TOKEN.CURL_OPEN)
    decls = yield ps.many(VarDecl)
    found_stmts = yield ps.many1(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    return AST.FUNDECL(kind=FunKind.FUNC,
                       fixity=None,
                       id=fname,
                       params=args,
                       type=typesig,
                       vardecls=decls,
                       stmts=found_stmts)
コード例 #15
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtFor():
    yield ps.token(TOKEN.FOR)
    yield ps.token(TOKEN.PAR_OPEN)
    initial = yield ps.times(ActStmt, 0, 1)
    initial = initial[0] if len(initial) > 0 else None
    yield ps.token(TOKEN.SEMICOLON)
    condition = yield ps.times(Exp, 0, 1)
    condition = condition[0] if len(condition) > 0 else None
    yield ps.token(TOKEN.SEMICOLON)
    update = yield ps.times(ActStmt, 0, 1)
    update = update[0] if len(update) > 0 else None
    yield ps.token(TOKEN.PAR_CLOSE)
    yield ps.token(TOKEN.CURL_OPEN)
    contents = yield ps.many(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    return AST.LOOP(init=initial,
                    cond=condition,
                    update=update,
                    stmts=contents)
コード例 #16
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def PrefixOpDecl():
    yield ps.token(TOKEN.PREFIX)
    operator = yield ps.token(TOKEN.OP_IDENTIFIER)
    yield ps.token(TOKEN.PAR_OPEN)
    varname = yield ps.token(TOKEN.IDENTIFIER)
    yield ps.token(TOKEN.PAR_CLOSE)
    typesig = yield ps.times(PreFunTypeSig, 0, 1)
    typesig = typesig[0] if len(typesig) > 0 else None
    yield ps.token(TOKEN.CURL_OPEN)
    decls = yield ps.many(VarDecl)
    found_stmts = yield ps.many1(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    return AST.FUNDECL(kind=FunKind.PREFIX,
                       fixity=None,
                       id=operator,
                       params=[varname],
                       type=typesig,
                       vardecls=decls,
                       stmts=found_stmts)
コード例 #17
0
def import_headers(json_string):  # Can return exception, so put in try-except
    load_packet = json.loads(json_string)
    temp_packet = {}
    temp_packet["depends"] = load_packet["depends"]
    temp_packet["globals"] = OrderedDict([(k, parse_type(v))
                                          for k, v in load_packet["globals"]])
    temp_packet["typesyns"] = OrderedDict([
        (k, parse_type(v)) for k, v in load_packet["typesyns"]
    ])
    temp_packet["functions"] = OrderedDict()
    for (uq, k), fix, kind, from_ts, to_t in load_packet["functions"]:
        if (FunUniq[uq], k) not in temp_packet["functions"]:
            temp_packet["functions"][(FunUniq[uq], k)] = []
        temp_packet["functions"][(FunUniq[uq], k)].append({
            "fixity":
            fix,
            "kind":
            FunKind[kind],
            "type":
            AST.FUNTYPE(from_types=list(map(parse_type, from_ts)),
                        to_type=parse_type(to_t))
        })
    return temp_packet
コード例 #18
0
ファイル: typechecker.py プロジェクト: W-M-T/gsc
def tokenToNode(token):
    if token.typ == TOKEN.INT:
        node = AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, "Int"))
        node._start_pos = Position()
        return node
    elif token.typ == TOKEN.CHAR:
        node = AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, "Char"))
        node._start_pos = Position()
        return node
    elif token.typ == TOKEN.BOOL:
        node = AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, "Bool"))
        node._start_pos = Position()
        return node
    elif token.typ == TOKEN.STRING:
        node = AST.LISTTYPE(type=AST.TYPE(val=AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, "Char"))))
        node._start_pos = Position()
        return node
    elif token.typ == TOKEN.EMPTY_LIST:
        node = AST.BASICTYPE(type_id=Token(Position(), TOKEN.TYPE_IDENTIFIER, "[]"))
        node._start_pos = Position()
        return node
    else:
        raise Exception('Unexpected token type encountered')
コード例 #19
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def IdField():
    i = yield ps.token(TOKEN.IDENTIFIER)
    found_fields = yield ps.many(ps.token(TOKEN.ACCESSOR))
    return AST.VARREF(id=i, fields=found_fields)
コード例 #20
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def Decl():
    found_val = yield VarDecl ^ FunDecl ^ TypeSyn ^ PrefixOpDecl ^ InfixOpDecl
    return AST.DECL(val=found_val)
コード例 #21
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def ImportName():
    found_name = yield AnyId
    found_alias = yield ps.times(ps.token(TOKEN.AS) >> AnyId, 0, 1)
    found_alias = found_alias[0] if len(found_alias) > 0 else None
    return AST.IMPORTNAME(name=found_name, alias=found_alias)
コード例 #22
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def ActStmt():
    found_val = yield Ass ^ FunCall
    return AST.ACTSTMT(val=found_val)
コード例 #23
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def Ass():
    var = yield IdField
    yield ps.token(TOKEN.OP_IDENTIFIER, cond=(lambda x: x == "="))
    expression = yield Exp
    return AST.ASSIGNMENT(varref=var, expr=expression)
コード例 #24
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtElse():
    yield ps.token(TOKEN.ELSE)
    yield ps.token(TOKEN.CURL_OPEN)
    contents = yield ps.many(Stmt)
    yield ps.token(TOKEN.CURL_CLOSE)
    return AST.CONDBRANCH(expr=None, stmts=contents)
コード例 #25
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def PrefixOpExp():
    op = yield ps.token(TOKEN.OP_IDENTIFIER)
    exp = yield ConvExp
    return AST.FUNCALL(kind=FunKind.PREFIX,
                       id=op,
                       args=[AST.DEFERREDEXPR(contents=[exp])])
コード例 #26
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def Exp():
    a = yield ConvExp
    b = yield ps.many(ExpMore)

    b = flatten(b)
    return AST.DEFERREDEXPR(contents=[a, *b])
コード例 #27
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtContinue():
    yield ps.token(TOKEN.CONTINUE)
    yield ps.token(TOKEN.SEMICOLON)
    return AST.CONTINUE()
コード例 #28
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtBreak():
    yield ps.token(TOKEN.BREAK)
    yield ps.token(TOKEN.SEMICOLON)
    return AST.BREAK()
コード例 #29
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def StmtRet():
    yield ps.token(TOKEN.RETURN)
    found_expr = yield ps.times(Exp, 0, 1)
    found_expr = found_expr[0] if len(found_expr) > 0 else None
    yield ps.token(TOKEN.SEMICOLON)
    return AST.RETURN(expr=found_expr)
コード例 #30
0
ファイル: parser.py プロジェクト: W-M-T/gsc
def AllImport():
    yield ps.token(TOKEN.IMPORTALL)
    found_name = yield ps.token(TOKEN.FILENAME)
    return AST.IMPORT(name=found_name, importlist=None)