--- esp.py- 2016-09-20 00:00:00.000000000 +0900 +++ esp.py 2016-09-22 00:00:00.000000000 +0900 @@ -201,7 +201,7 @@ def tree_kwd(lst, kdic): return lst e = lst[0] step = lambda e, i: [ e ] + tree_kwd( lst[i:], kdic ) - top_is = lambda lst, k, v: len(lst) > 0 and lst[0][:2] == [ k, v ] + top_is = lambda lst, t: len(lst) > 0 and lst[0][:len(t)] == t if type(e) is not list: return step(e, 1) (k, v) = e[:2] @@ -216,26 +216,27 @@ def tree_kwd(lst, kdic): r = tree_kwd( lst[1:], kdic ) return [ [ k, v, r[0] ] ] + r[1:] if v == 'if' and len( lst[2:] ) > 0: - if lst[1][:2] != [ 'br_s', '(' ]: + if not top_is( lst[1:], [ 'br_s', '(' ] ): err_not_found("'(' after 'if'") r = tree_kwd( lst[2:], kdic ) e = [ k, v, lst[1], r.pop(0) ] - if top_is(r, 'etc', ';'): + if top_is(r, [ 'etc', ';' ] ): r.pop(0) - if top_is(r, 'kwd', 'else'): + if top_is(r, [ 'kwd', 'else' ] ): e += [ r.pop(0)[2] ] return [ e ] + r if v in [ 'while', 'for' ] and len( lst[2:] ) > 0: - if lst[1][:2] != [ 'br_s', '(' ]: + if not top_is( lst[1:], [ 'br_s', '(' ] ): err_not_found("'(' after '{}'".format(v)) r = tree_kwd( lst[2:], kdic ) e = [ k, v, lst[1], r.pop(0) ] return [ e ] + r if v == 'struct': - (name, i) = ( lst[1][1], 2 ) if lst[1][0] == 'name' else (None, 1) - (body, i) = ( lst[i], i+1 ) if lst[i][:2] == [ 'br_s', '{' ] else (None, i) + (name, i) = ( lst[1][1], 2 ) if top_is( lst[1:], [ 'name' ] ) else (None, 1) + (body, i) = ( lst[i], i+1 ) if top_is( lst[i:], [ 'br_s', '{' ] ) else (None, i) e = [ 'struct', name, body ] - e = [ 'type' if lst[i][0] == 'name' else 'sdef', e ] + grp = 'sdef' if top_is( lst[i:], [ 'etc', ';' ] ) else 'type' + e = [ grp, e ] return step(e, i) e = e[:2] + tree_kwd( e[2:], kdic ) return step(e, 1) @@ -246,18 +247,22 @@ def tree_type(lst): e = lst[0] step = lambda e, i: [ e ] + tree_type( lst[i:] ) if e[0] == 'br_s': - e = [ e[0], e[1], tree_type( e[2] ) ] + e = e[:2] + [ tree_type( e[2] ) ] return step(e, 1) + + tree_type_br_s = lambda br_s: tree_type( [ br_s ] )[0] if e[0] == 'fdef': - e4 = tree_type( [ e[4] ] )[0] - e = [ e[0], e[1], e[2], e[3], e4 ] + e = e[:4] + [ tree_type_br_s( e[4] ) ] return step(e, 1) if e[0] == 'kwd' and e[1] in [ 'if', 'while', 'for' ]: - try_blk = lambda t: tree_type( [ t ] )[0] if t[:2] == [ 'br_s', '{' ] else t + try_blk = lambda t: tree_type_br_s(t) if t[:2] == [ 'br_s', '{' ] else t e = e[:2] + [ try_blk(t) for t in e[2:] ] return step(e, 1) + if ( e[0] == 'type' or e[0] == 'sdef' ) and e[1][0] == 'struct' and e[1][2] is not None: + f = lambda s: s[:2] + [ tree_type_br_s( s[2] ) ] + e = e[:1] + [ f( e[1] ) ] if e[0] == 'type' and len( lst[1:] ) > 0: - e = [ e[0], e[1], lst[1] ] + e = e[:2] + [ lst[1] ] return step(e, 2) return step(e, 1) @@ -396,10 +401,17 @@ def set_val(name, val, info): return val err_not_found(name) +def add_order(name, env): + k = '@order' + if k not in env: + env[k] = [] + env.get(k).append(name) + def new_val(name, val, info): env = get_call_inf(info).get('env') if name not in env: env[name] = val + add_order(name, env) return val err_exit("alredy exist '{}'".format(name)) @@ -612,6 +624,23 @@ def do_type_arr(e, val, info): val = [ None ] * n return val +def sdef_name(name): + return 'sdef@' + name + +def do_type_struct(e, val, info): + # [ 'struct', name, body ] + if val is None: + return {} + (name, body) = e[1:3] + if body is None: + body = get_val( sdef_name(name), info ) + benv = {} + do_blk(None, benv, body, info) + names = benv.get('@order') + vals = do_comma(val[2][0], info) # val is [ 'br_s', '{', [ [ 'op', ',' ... ] ] ] + vals += [ None ] * ( len(names) - len(vals) ) + return dict( zip(names, vals) ) + def do_type(expr, info): for e in flat_comma( expr[2] ): val = None @@ -620,14 +649,20 @@ def do_type(expr, info): e = e[2] if e[0] == 'arr': val = do_type_arr(e, val, info) + elif expr[1][0] == 'struct': + val = do_type_struct( expr[1], val, info ) elif val: val = do_expr(val, info) - elif expr[1][0] == 'struct': - val = {} name = e[1] new_val(name, val, info) return None +def do_sdef(expr, info): + # [ 'sdef', [ 'struct', name, body ] ] + (name, body) = expr[1][1:3] + if name and body: + new_val( sdef_name(name), body, info ) + def do_expr(expr, info): if info.get('verb') >= 2: print('expr={}'.format(expr)) @@ -658,8 +693,10 @@ def do_expr(expr, info): return do_fcall(v, args, info) if k == 'type': return do_type(expr, info) + if k == 'sdef': + return do_sdef(expr, info) - if k in [ 'fproto', 'etc', 'fdef', 'sdef' ]: # do nothing !!! + if k in [ 'fproto', 'etc', 'fdef' ]: # do nothing !!! return None warn_no_sup('do_expr', '[k, v]', [k, v])