001: // Copyright (c) Corporation for National Research Initiatives
002:
003: package org.python.compiler;
004:
005: import java.util.Vector;
006:
007: import org.python.parser.ParseException;
008: import org.python.parser.PythonGrammarTreeConstants;
009: import org.python.parser.Visitor;
010: import org.python.parser.ast.Assign;
011: import org.python.parser.ast.Name;
012: import org.python.parser.ast.Suite;
013: import org.python.parser.ast.Tuple;
014: import org.python.parser.ast.argumentsType;
015: import org.python.parser.ast.exprType;
016: import org.python.parser.ast.stmtType;
017:
018: public class ArgListCompiler extends Visitor implements
019: PythonGrammarTreeConstants {
020: public boolean arglist, keywordlist;
021: public exprType[] defaults;
022: public Vector names;
023: public Vector fpnames;
024: public Vector init_code;
025:
026: public ArgListCompiler() {
027: arglist = keywordlist = false;
028: defaults = null;
029: names = new Vector();
030: fpnames = new Vector();
031: init_code = new Vector();
032: }
033:
034: public void reset() {
035: arglist = keywordlist = false;
036: defaults = null;
037: names.removeAllElements();
038: init_code.removeAllElements();
039: }
040:
041: public void appendInitCode(Suite node) {
042: int n = node.body.length;
043: stmtType[] newtree = new stmtType[init_code.size() + n];
044: init_code.copyInto(newtree);
045: System.arraycopy(node.body, 0, newtree, init_code.size(), n);
046: node.body = newtree;
047: }
048:
049: public exprType[] getDefaults() {
050: return defaults;
051: }
052:
053: public void visitArgs(argumentsType args) throws Exception {
054: for (int i = 0; i < args.args.length; i++) {
055: String name = (String) visit(args.args[i]);
056: names.addElement(name);
057: if (args.args[i] instanceof Tuple) {
058: Assign ass = new Assign(
059: new exprType[] { args.args[i] }, new Name(name,
060: Name.Load, args.args[i]), args.args[i]);
061: init_code.addElement(ass);
062: }
063: }
064: if (args.vararg != null) {
065: arglist = true;
066: names.addElement(args.vararg);
067: }
068: if (args.kwarg != null) {
069: keywordlist = true;
070: names.addElement(args.kwarg);
071: }
072:
073: defaults = args.defaults;
074: for (int i = 0; i < defaults.length; i++) {
075: if (defaults[i] == null)
076: throw new ParseException(
077: "non-default argument follows default argument",
078: args.args[args.args.length - defaults.length
079: + i]);
080: }
081: }
082:
083: public Object visitName(Name node) throws Exception {
084: if (node.ctx != Name.Store)
085: return null;
086:
087: if (fpnames.contains(node.id)) {
088: throw new ParseException("duplicate argument name found: "
089: + node.id, node);
090: }
091: fpnames.addElement(node.id);
092: return node.id;
093: }
094:
095: public Object visitTuple(Tuple node) throws Exception {
096: StringBuffer name = new StringBuffer("(");
097: int n = node.elts.length;
098: for (int i = 0; i < n - 1; i++) {
099: name.append(visit(node.elts[i]));
100: name.append(", ");
101: }
102: name.append(visit(node.elts[n - 1]));
103: name.append(")");
104: return name.toString();
105: }
106: }
|