summaryrefslogtreecommitdiff
path: root/src/runtime/java/org/grammaticalframework/pgf/Expr.java
blob: db0876bf89ce1162668e76f0c2add53c5aff1ebe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package org.grammaticalframework.pgf;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;

/** This class is a representation of an abstract syntax tree.
 */
public class Expr implements Serializable {
		private static final long serialVersionUID = 1148602474802492674L;
	
		private Pool pool;
		private Object master;
		private long ref;

		Expr(Pool pool, Object master, long ref) {
			this.pool   = pool;
			this.master = master;
			this.ref    = ref;
		}

		/** Constructs an expression which represents a string literal */
		public Expr(String s) {
			if (s == null)
				throw new IllegalArgumentException("s == null");

			this.pool   = new Pool();
			this.master = null;
			this.ref    = initStringLit(s, pool.ref);  
		}

		/** Constructs an expression which represents an integer literal */
		public Expr(int d) {
			this.pool   = new Pool();
			this.master = null;
			this.ref    = initIntLit(d, pool.ref);  
		}

		/** Constructs an expression which represents a floating point literal */
		public Expr(double f) {
			this.pool   = new Pool();
			this.master = null;
			this.ref    = initFloatLit(f, pool.ref);  
		}

		/** Constructs an expression which is a function application
		 * @param fun The name of the top-level function.
		 * @param args the arguments for the function.
		 */
		public Expr(String fun, Expr... args) {
			if (fun == null)
				throw new IllegalArgumentException("fun == null");
			for (int i = 0; i < args.length; i++) {
				if (args[i] == null)
					throw new IllegalArgumentException("the "+(i+1)+"th argument is null");
			}

			this.pool   = new Pool();
			this.master = args;
			this.ref    = initApp(fun, args, pool.ref);
		}

		/** Constructs an expression which is an application
		 * of the first expression to a list of arguments.
		 */
		public static Expr apply(Expr fun, Expr... args) {
			if (fun == null)
				throw new IllegalArgumentException("fun == null");
			for (int i = 0; i < args.length; i++) {
				if (args[i] == null)
					throw new IllegalArgumentException("the "+(i+1)+"th argument is null");
			}

			Object[] master = new Object[args.length+1];
			master[0] = fun;
			for (int i = 0; i < args.length; i++) {
				master[i+1] = args[i].master;
			}

            Pool pool = new Pool();
			return new Expr(pool, master, initApp(fun, args, pool.ref));
		}

		/** If the method is called on an expression which is 
		 * a function application, then it is decomposed into 
		 * a function name and a list of arguments. If this is not 
		 * an application then the result is null. */
		public native ExprApplication unApp();

		/** If the method is called on an expression which is 
		 * a meta variable, then it will return the variable's id.
		 * If this is not a meta variable then the result is -1. */
		public native int unMeta();
		
		/** If the method is called on an expression which is 
		 * a string literal, then it will return the string value.
		 * If this is not a string literal then the result is null. */
		public native String unStr();

		/** An implementation for the visitor pattern. The method uses
		 * reflection to find the relevant methods from the visitor object */
		public native void visit(Object visitor);

		/** Returns the expression as a string in the GF syntax */
		public String toString() {
			return showExpr(ref);
		}

		/** Computes the number of functions in the expression */
		public native int size();

		/** Reads a string in the GF syntax for abstract expressions
		 * and returns an object representing the expression. */
		public static native Expr readExpr(String s) throws PGFError;

		/** Compares the current expression with another expression by value. 
		 * @return True if the expressions are equal. */
		public native boolean equals(Object e);

		public native int hashCode();

		private static native String showExpr(long ref);

		private static native long initStringLit(String s, long pool);
		private static native long initIntLit(int d, long pool);
		private static native long initFloatLit(double f, long pool);
		private static native long initApp(Expr   fun, Expr[] args, long pool);
		private static native long initApp(String fun, Expr[] args, long pool);

		private void writeObject(ObjectOutputStream out) throws IOException {
			out.writeObject(showExpr(ref));
		}
		
		private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
			Expr e = readExpr((String) in.readObject());
			pool   = e.pool;
			master = e.master;
			ref    = e.ref;
		}
		
		static { 
			System.loadLibrary("jpgf");
		}
}