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 defconst(prefix, loc): name = prefix + src.gettok() src.need('=') value = expr() const = {'isa': 'const', 'name': name, 'value': expr2str(value['value']), 'type': value['value']['type']} loc.append(const) return const
def hier2(): l = hier1() while src.match('['): indx = hier21() src.need(']') l = {'isa': 'operation', 'array': l, 'index': indx, 'op': 'index'} return l
def dowhile(): #src.need('(') cond = expr() src.need('{') body = cpnd() return {'isa': 'while', 'condition': cond, 'body': body}
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 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 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 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 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'}