def defvar(prefix, loc): names = [] while True: name = prefix + src.gettok() names.append(name) if not src.match(','): break src.need(':') volume = '' if src.match('['): volume = expr2str(hier21()) src.need(']') level = 0 while src.match('*'): level += 1 t = src.gettok() #if t == 'hash': # t = 'char*' varlist = [] for name in names: varlist.append({'isa': 'var', 'name': name, 'type': t, 'level': level, 'volume': volume}) # [a, b, c] -> [LOCAL] loc.extend(varlist) return varlist
def stmt(): s = {'isa': '[statement]'} if src.match('{'): s = cpnd() elif src.match('if'): s = doif() elif src.match('while'): s = dowhile() elif src.match('return'): s = doreturn() elif src.match('break'): s = dobreak() elif src.match('continue'): s = docontinue() elif src.match('const'): k = defconst('', local_consts) # local_consts.append(k) s = {'isa': 'const definition', 'value': [k]} elif src.match('var'): vl = defvar('', local_vars) # local_vars.extend(vl) s = {'isa': 'var definition', 'value': vl} elif src.match('\n'): pass else: src.catch_nl = True #print('token BEFORE: %s' % src.token()) s = expr() #print('token AFTER: %s' % src.token()) src.need('\n') src.catch_nl = False return s
def hier6(): while True: if src.match('+'): r = hier5() return {'isa': 'operation', 'right': r, 'op': 'positive'} elif src.match('-'): r = hier5() return {'isa': 'operation', 'right': r, 'op': 'negative'} else: return hier5() break
def hier11(): l = hier10() while True: if src.match('+'): r = hier10() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'add'} elif src.match('-'): r = hier10() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'sub'} else: break return l
def hier14(): l = hier13() while True: if src.match('=='): r = hier13() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'eq'} elif src.match('!='): r = hier13() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'ne'} else: break return l
def hier12(): l = hier11() while True: if src.match('<<'): r = hier11() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'shl'} elif src.match('>>'): r = hier11() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'shr'} else: break return l
def hier3(): l = hier2() while src.match('('): arglist = [] while True: a = hier21() if a['isa'] != None: arglist.append(a) if not src.match(','): break src.need(')') l = {'isa': 'operation', 'func': l, 'arglist': arglist, 'op': 'call'} return l
def hier10(): l = hier9() while True: if src.match('*'): r = hier9() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'mul'} elif src.match('/'): r = hier9() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'div'} elif src.match('%'): r = hier9() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'mod'} else: break return l
def hier7(): if src.match('&'): r = hier6() l = {'isa': 'operation', 'right': r, 'op': 'ref'} else: l = hier6() return l
def hier8(): while src.match('*'): r = hier7() return {'isa': 'operation', 'right': r, 'op': 'deref'} else: return hier7()
def hier5(): while src.match('->'): r = hier4() l = {'isa': 'operation', 'pointer': l, 'field': r, 'op': 'arrow'} else: l = hier4() return l
def hier2(): l = hier1() while src.match('['): indx = hier21() src.need(']') l = {'isa': 'operation', 'array': l, 'index': indx, 'op': 'index'} return l
def hier18(): if src.match('not'): r = hier17() l = {'isa': 'operation', 'right': r, 'op': 'not'} else: l = hier17() return l
def hier1(): l = hier0() while src.match('.'): r = hier0() #print('DOT: %s :: %s' % (l['value'], r['value'])) l['value'] = l['value'] + '_' + r['value'] return l
def hier21(): l = hier20() while True: if src.match('='): r = hier20() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'assign'} else: break return l
def hier13(): l = hier12() while True: if src.match('<'): r = hier12() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'lt'} elif src.match('>'): r = hier12() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'gt'} elif src.match('<='): r = hier12() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'le'} elif src.match('>='): r = hier12() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'ge'} else: break return l
def cmpl(f): src.opens(f) filename = f.split('.')[0] if filename != 'main': unit['name'] = filename while not src.eof(): if src.match('const'): defconst(unit['name'] + '_', unit['const']) elif src.match('var'): defvar(unit['name'] + '_', unit['var']) elif src.match('define'): defun() elif src.match('import'): doimport() else: break
def doif(): cond = expr() src.need('{') _then = cpnd() if src.match('else'): src.need('{') _else = cpnd() return {'isa': 'if', 'condition': cond, 'then': _then, 'else': _else} return {'isa': 'if', 'condition': cond, 'then': _then}
def defun(): global params, local_consts, local_vars params = [] local_consts = [] local_vars = [] name = src.gettok() spec = '' if name[0] == '_': spec = 'static ' if name != 'main': name = unit['name'] + '_' + name src.need('(') if not src.match(')'): while True: arg_name = src.gettok() arg_lvl = 0 while src.match('*'): arg_lvl += 1 arg_type = src.gettok() params.append({'isa': 'param', 'name': arg_name, 'type': arg_type, 'level': arg_lvl}) if not src.match(','): break src.need(')') src.need('{') global func_type func_type = 'void' # see doreturn code = cpnd() unit['func'].append({'isa': 'func', 'spec': spec, 'name': name, 'params': params, 'type': func_type, 'code': code, 'local consts': local_consts, 'local vars': local_vars}) params = [] local_consts = [] local_vars = []
def doimport(): imp = [] imp.append(src.gettok()) while src.match('.'): imp.append(src.gettok()) name = '' ispath = False if len(imp) > 1: # get path from DOT. record name = imp[0] for s in imp[1:]: name = (name + '/' + s) ispath = True else: name = imp[0] # check if not imported for i in unit['import']: if i['name'] == name: print('already imported') return filename = name + '.cstar' if os.path.isfile(filename): # UNIT unit['import'].append({'name': name, 'extern': False}) import_unit(filename) elif os.path.isdir(name): # PACKAGE unit['import'].append({'name': name, 'extern': False}) import_package(name) else: # UNKNOWN unit['import'].append({'name': name, 'extern': True})
def cpnd(): b = {'isa': 'block', 'value': []} while not src.match('}'): s = stmt() b['value'].append(s) return b
def hier0(): if src.match('('): k = hier18() src.need(')') return k t = src.token() #print('HIER: %s' % t) if t[0].isdigit(): _type = 'integer' if src.token()[0:2] == '0x': _type = 'unsigned' value = int(src.token(), 0) src.gettok() return {'isa': 'atom', 'type': _type, 'value': value} elif t[0].isalpha() or t[0] == '_': a = str(src.token()) c = None ref = None # find in arglist for arg in params: if a == arg['name']: ref = arg c = a break # if not found in args if c == None: # find in locals for lv in local_vars: if a == lv['name']: ref = lv c = a break # if not arg or local find global: if c == None: b = unit['name'] + '_' + a for em in unit['var']: if b == em['name']: ref = em c = b break for em in unit['const']: if b == em['name']: ref = em c = b break for em in unit['func']: if b == em['name']: ref = em c = b break if c == None: c = a undef(c) src.gettok() return {'isa': 'atom', 'type': 'name', 'value': c, 'ref': ref} elif t[0] == '#': value = str(src.token()) src.gettok() return {'isa': 'atom', 'type': 'hashtag', 'value': '"' + value + '"'} elif t[0] == '"': value = str(src.token()) src.gettok() return {'isa': 'atom', 'type': 'string', 'value': value} return {'isa': 'unknown'}
def hier19(): l = hier18() while src.match('and'): r = hier18() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'and'} return l
def hier17(): l = hier16() while src.match('|'): r = hier16() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'bit_or'} return l
def hier15(): l = hier14() while src.match('&'): r = hier14() l = {'isa': 'operation', 'left': l, 'right': r, 'op': 'bit_and'} return l
def hier9(): l = hier8() if src.match('as'): l = {'isa': 'operation', 'left': l, 'op': 'as'} return l