[Python-checkins] python/nondist/sandbox/ast astmodule.c,1.2,1.3

jhylton@sourceforge.net jhylton@sourceforge.net
Mon, 15 Apr 2002 20:59:48 -0700


Update of /cvsroot/python/python/nondist/sandbox/ast
In directory usw-pr-cvs1:/tmp/cvs-serv23898

Modified Files:
	astmodule.c 
Log Message:
Lots more conversion code, which handles many expressions.


Index: astmodule.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/ast/astmodule.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** astmodule.c	12 Apr 2002 15:55:25 -0000	1.2
--- astmodule.c	16 Apr 2002 03:59:46 -0000	1.3
***************
*** 1,3 ****
--- 1,7 ----
  #include "Python.h"
+ 
+ #undef NDEBUG
+ #include <assert.h>
+ 
  #include "Python-ast.h"
  
***************
*** 8,14 ****
  #include "graminit.h"
  
- extern grammar _PyParser_Grammar; /* From graminit.c */
  
! extern stmt_ty Global(identifier name);
  
  /* XXX should be seq */
--- 12,18 ----
  #include "graminit.h"
  
  
! 
! extern grammar _PyParser_Grammar; /* From graminit.c */
  
  /* XXX should be seq */
***************
*** 17,34 ****
  {
      /* global_stmt: 'global' NAME (',' NAME)* */
!     identifier *name;
      REQ(n, global_stmt);
!     n = CHILD(n, 1);
!     name = PyString_InternFromString(STR(n));
!     if (!name)
  	return NULL;
!     return Global(name);
  }
  
! static stmt_ty
! ast_for_stmt(node *n)
  {
      int i;
  
      REQ(n, stmt);
      assert(NCH(n) == 1);
--- 21,310 ----
  {
      /* global_stmt: 'global' NAME (',' NAME)* */
!     identifier name;
!     asdl_seq *s;
!     int i;
! 
      REQ(n, global_stmt);
!     s = asdl_seq_new(NCH(n) / 2);
!     for (i = 1; i < NCH(n); i += 2) {
! 	name = PyString_InternFromString(STR(CHILD(n, i)));
! 	if (!name)
! 	    return NULL;
! 	if (asdl_seq_append(s, name) < 0)
! 	    return NULL;
!     }
!     return Global(s);
! }
! 
! static cmpop_ty
! ast_for_comp_op(node *n)
! {
!     /* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'
!                |'is' 'not'
!     */
!     REQ(n, comp_op);
!     if (NCH(n) == 1) {
! 	n = CHILD(n, 0);
! 	switch (TYPE(n)) {
! 	case LESS:	
! 	    return Lt;
! 	case GREATER:	
! 	    return Gt;
! 	case EQEQUAL:			/* == */
! 	case EQUAL:
! 	    return Eq;
! 	case LESSEQUAL:	
! 	    return LtE;
! 	case GREATEREQUAL: 
! 	    return GtE;
! 	case NOTEQUAL:	
! 	    return NotEq;
! 	case NAME:	
! 	    if (strcmp(STR(n), "in") == 0) 
! 		return In;
! 	    if (strcmp(STR(n), "is") == 0) 
! 		return Is;
! 	}
!     }
!     else if (NCH(n) == 2) {
! 	switch (TYPE(CHILD(n, 0))) {
! 	case NAME:	
! 	    if (strcmp(STR(CHILD(n, 1)), "in") == 0)
! 		return NotIn;
! 	    if (strcmp(STR(CHILD(n, 0)), "is") == 0)
! 		return IsNot;
! 	}
!     }
!     return 0;
! }
! 
! static expr_ty
! ast_for_lambdef(node *n)
! {
!     return NULL;
! }
! 
! static expr_ty
! ast_for_atom(node *n)
! {
!     /* atom: '(' [testlist] ')' | '[' [listmaker] ']' 
!            | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+ 
!     */
!     node *ch = CHILD(n, 0);
!     switch (TYPE(ch)) {
!     case NAME: {
! 	return Name(PyString_InternFromString(STR(ch)));
! 	break;
!     }
!     case STRING:
! 	return Str(PyString_FromString("darn, strings are hard to parse"));
! 	break;
!     case NUMBER:
! 	return Num(PyString_FromString("darn, numbers are hard too"));
! 	break;
! 	/* XXX other cases... */
!     default:
! 	fprintf(stderr, "unhandled atom %d\n", TYPE(ch));
!     }
!     return NULL;
! }
! 
! static expr_ty
! ast_for_expr(node *n)
! {
!     /* handle the full range of simple expressions
!        test: and_test ('or' and_test)* | lambdef
!        and_test: not_test ('and' not_test)*
!        not_test: 'not' not_test | comparison
!        comparison: expr (comp_op expr)*
!        expr: xor_expr ('|' xor_expr)*
!        xor_expr: and_expr ('^' and_expr)*
!        and_expr: shift_expr ('&' shift_expr)*
!        shift_expr: arith_expr (('<<'|'>>') arith_expr)*
!        arith_expr: term (('+'|'-') term)*
!        term: factor (('*'|'/'|'%'|'//') factor)*
!        factor: ('+'|'-'|'~') factor | power
!        power: atom trailer* ('**' factor)*
!     */
! 
!     asdl_seq *seq;
!     operator_ty op = 0;
!     int i;
! 
!  loop:
!     switch (TYPE(n)) {
!     case test:
! 	if (TYPE(CHILD(n, 0)) == lambdef)
! 	    return ast_for_lambdef(CHILD(n, 0));
! 	if (NCH(n) == 1) {
! 	    n = CHILD(n, 0);
! 	    goto loop;
! 	}
! 	seq = asdl_seq_new(NCH(n) / 2 + 1);
! 	for (i = 0; i < NCH(n); i += 2)
! 	    asdl_seq_append(seq, ast_for_expr(CHILD(n, i)));
! 	return BoolOp(Or, seq);
! 	break;
!     case and_test:
! 	if (NCH(n) == 1) {
! 	    n = CHILD(n, 0);
! 	    goto loop;
! 	}
! 	seq = asdl_seq_new(NCH(n) / 2 + 1);
! 	for (i = 0; i < NCH(n); i += 2)
! 	    asdl_seq_append(seq, ast_for_expr(CHILD(n, i)));
! 	return BoolOp(And, seq);
! 	break;
!     case not_test:
! 	if (NCH(n) == 1) {
! 	    n = CHILD(n, 0);
! 	    goto loop;
! 	}
! 	else
! 	    return UnaryOp(Not, ast_for_expr(CHILD(n, 1)));
!     case comparison:
! 	if (NCH(n) == 1) {
! 	    n = CHILD(n, 0);
! 	    goto loop;
! 	} else {
! 	    asdl_seq *ops, *cmps;
! 	    ops = asdl_seq_new(NCH(n) / 2 + 1);
! 	    cmps = asdl_seq_new(NCH(n) / 2 + 1);
! 	    for (i = 1; i < NCH(n); i += 2) {
! 		asdl_seq_append(ops, (void *)ast_for_comp_op(CHILD(n, i)));
! 		asdl_seq_append(cmps, (void *)ast_for_expr(CHILD(n, i + 1)));
! 	    }
! 	    return Compare(ast_for_expr(CHILD(n, 0)), ops, cmps);
! 	}
! 	break;
! 
!     /* The next five cases all handle BinOps.  The main body of code
!        is the same in each case, but the switch turned inside out to
!        reuse the code for each type of operator.
!      */
!     case expr:
!     case xor_expr:
!     case and_expr:
!     case shift_expr:
!     case arith_expr:
!     case term:
! 	if (NCH(n) == 1) {
! 	    n = CHILD(n, 0);
! 	    goto loop;
! 	}
! 	switch (TYPE(CHILD(n, 1))) {
! 	case VBAR:
! 	    op = BitOr;
! 	    break;
! 	case CIRCUMFLEX:
! 	    op = BitXor;
! 	    break;
! 	case AMPER:
! 	    op = BitAnd;
! 	    break;
! 	case LEFTSHIFT:
! 	    op = LShift;
! 	    break;
! 	case RIGHTSHIFT:
! 	    op = RShift;
! 	    break;
! 	case PLUS:
! 	    op = Add;
! 	    break;
! 	case MINUS:
! 	    op = Sub;
! 	    break;
! 	case STAR:
! 	    op = Mult;
! 	    break;
! 	case SLASH:
! 	    op = Div;
! 	    break;
! 	case DOUBLESLASH:
! 	    op = FloorDiv;
! 	    break;
! 	case PERCENT:
! 	    op = Mod;
! 	    break;
! 	}
! 	return BinOp(ast_for_expr(CHILD(n, 0)), op,
! 		     ast_for_expr(CHILD(n, 2)));
! 	break;
!     case factor:
! 	if (NCH(n) == 1) {
! 	    n = CHILD(n, 0);
! 	    goto loop;
! 	}
! 	switch (TYPE(CHILD(n, 0))) {
! 	case PLUS:
! 	    return UnaryOp(UAdd, ast_for_expr(CHILD(n, 1)));
! 	    break;
! 	case MINUS:
! 	    return UnaryOp(USub, ast_for_expr(CHILD(n, 1)));
! 	    break;
! 	case TILDE:
! 	    return UnaryOp(Invert, ast_for_expr(CHILD(n, 1)));
! 	    break;
! 	}
! 	break;
!     case power:
! 	if (NCH(n) == 1) {
! 	    expr_ty e = ast_for_atom(CHILD(n, 0));
! 	    assert(e);
! 	    return e;
! 	}
  	return NULL;
! 	break;
!     }
!     /* should never get here */
!     return NULL;
  }
  
! static asdl_seq *
! seq_for_testlist(node *n)
  {
+     asdl_seq *seq;
      int i;
  
+     REQ(n, testlist);
+     seq = asdl_seq_new(NCH(n) / 2);
+     for (i = 0; i < NCH(n); i += 2) {
+ 	asdl_seq_append(seq, ast_for_expr(CHILD(n, i)));
+     }
+     return seq;
+ }
+ 
+ static stmt_ty
+ ast_for_expr_stmt(node *n)
+ {
+     REQ(n, expr_stmt);
+     /* expr_stmt: testlist (augassign testlist | ('=' testlist)*) 
+        testlist: test (',' test)* [',']
+        augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' 
+ 	        | '<<=' | '>>=' | '**=' | '//='
+        test: ... here starts the operator precendence dance 
+      */
+ 
+     if (NCH(n) == 1) {
+ 	/* a bare expression */
+ 	node *ch = CHILD(n, 0);
+ 	REQ(ch, testlist);
+ 	if (NCH(ch) == 1) {
+ 	    /* a simple expression */
+ 	    return Expr(ast_for_expr(CHILD(ch, 0)));
+ 	}
+ 	else 
+ 	    return Expr(Tuple(seq_for_testlist(ch)));
+     } else if (TYPE(CHILD(n, 1)) == augassign) {
+ 	/* an augmented assignment */
+     } else {
+ 	/* a normal assignment */
+     }
+     return NULL;
+ }
+ 
+ static stmt_ty
+ ast_for_stmt(node *n)
+ {
      REQ(n, stmt);
      assert(NCH(n) == 1);
***************
*** 47,51 ****
  	switch (TYPE(n)) {
  	case expr_stmt:
! 	    fprintf(stderr, "expr_stmt NCH=%d\n", NCH(n));
  	    break;
  	case global_stmt:
--- 323,327 ----
  	switch (TYPE(n)) {
  	case expr_stmt:
! 	    return ast_for_expr_stmt(n);
  	    break;
  	case global_stmt:
***************
*** 65,78 ****
  {
      int i;
  
      REQ(n, file_input);
      fprintf(stderr, "file_input NCH=%d\n", NCH(n));
      for (i = 0; i < NCH(n); i++) {
! 	if (TYPE(CHILD(n, i)) == stmt)
! 	    ast_for_stmt(CHILD(n, i));
  	else
  	    fprintf(stderr, "skipping %d\n", TYPE(CHILD(n, i)));
      }
!     return NULL;
  }
  
--- 341,365 ----
  {
      int i;
+     asdl_seq *stmts;
+     stmt_ty s;
  
      REQ(n, file_input);
+     stmts = asdl_seq_new(NCH(n) / 2);
      fprintf(stderr, "file_input NCH=%d\n", NCH(n));
      for (i = 0; i < NCH(n); i++) {
! 	if (TYPE(CHILD(n, i)) == stmt) {
! 	    s = ast_for_stmt(CHILD(n, i));
! 	    if (!s) {
! 		asdl_seq_free(stmts);
! 		return NULL;
! 	    }
! 	    if (asdl_seq_append(stmts, s) < 0) {
! 		return NULL;
! 	    }
! 	}
  	else
  	    fprintf(stderr, "skipping %d\n", TYPE(CHILD(n, i)));
      }
!     return Module(stmts);
  }
  
***************
*** 82,85 ****
--- 369,373 ----
      node *n;
      perrdetail err;
+     mod_ty m;
  
      if (!PyString_Check(src)) {
***************
*** 98,102 ****
      }
  
!     ast_for_module(n);
  
      Py_INCREF(Py_None);
--- 386,394 ----
      }
  
!     m = ast_for_module(n);
!     if (!m)
! 	return NULL;
! 
!     fprintf(stderr, "module %X, stmts = %d\n", m, m->v.Module.body->used);
  
      Py_INCREF(Py_None);