001: /*
002: * Expression.java
003: *
004: * Copyright (C) 2002 Peter Graves
005: * $Id: Expression.java,v 1.1.1.1 2002/09/24 16:09:00 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: public class Expression {
025: protected final String name;
026: protected final int arity;
027:
028: public Expression(String name) {
029: this (name, -1);
030: }
031:
032: public Expression(String name, int arity) {
033: this .name = name;
034: this .arity = arity;
035: }
036:
037: public final String getName() {
038: return name;
039: }
040:
041: public final int getArity() {
042: return arity;
043: }
044:
045: public boolean matches(LocalTag tag) {
046: if (!name.equals(tag.getMethodName()))
047: return false;
048: if (arity >= 0) {
049: int n = getArity(tag.getCanonicalSignature());
050: if (n < 0 || n == arity)
051: return true;
052: else
053: return false;
054: }
055: return true;
056: }
057:
058: // BUG! This function is not aware of comments!
059: public static int getArity(String s) {
060: if (s == null)
061: return -1;
062: int start = -1;
063: int parenCount = 0;
064: int arity = 0;
065: char quoteChar = '\0';
066: boolean inQuote = false;
067: for (int i = 0; i < s.length(); i++) {
068: char c = s.charAt(i);
069: if (start < 0) {
070: if (c == '(')
071: start = i + 1;
072: continue;
073: }
074: // Reaching here, we've seen the opening paren of the argument list.
075: if (inQuote) {
076: if (c == quoteChar)
077: inQuote = false;
078: continue;
079: }
080: // Not in a quoted string.
081: if (c == '"' || c == '\'') {
082: inQuote = true;
083: quoteChar = c;
084: continue;
085: }
086: if (c == ',') {
087: if (parenCount == 0) // Top level.
088: ++arity;
089: continue;
090: }
091: if (c == '(') {
092: ++parenCount;
093: continue;
094: }
095: if (c == ')') {
096: --parenCount;
097: if (parenCount < 0) {
098: // Closing paren, done.
099: if (arity == 0) {
100: // We haven't seen a comma.
101: String enclosed = s.substring(start, i);
102: boolean isBlank = true;
103: for (int j = 0; j < enclosed.length(); j++) {
104: if (!Character.isWhitespace(enclosed
105: .charAt(j))) {
106: isBlank = false;
107: break;
108: }
109: }
110: if (!isBlank)
111: arity = 1;
112: } else
113: ++arity;
114: return arity;
115: }
116: continue;
117: }
118: }
119: return -1;
120: }
121: }
|