Back to index

wims  3.65+svn20090927
Compiler.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007-2008 Mihai Preda.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 package org.javia.arity;
00018 
00022 class Compiler {
00023     private final SyntaxException exception = new SyntaxException();
00024     private final Lexer lexer = new Lexer(exception);
00025     private final RPN rpn     = new RPN(exception);
00026     private final DeclarationParser declParser = new DeclarationParser(exception);
00027     private final OptCodeGen codeGen = new OptCodeGen(exception);
00028     private final SimpleCodeGen simpleCodeGen = new SimpleCodeGen(exception);
00029     private final Declaration decl   = new Declaration();
00030 
00031     double eval(Symbols symbols, String expression) throws SyntaxException {
00032         rpn.setConsumer(simpleCodeGen.setSymbols(symbols));
00033         lexer.scan(expression, rpn);
00034         return simpleCodeGen.getValue();
00035     }
00036 
00037     FunctionAndName compile(Symbols symbols, String source) throws SyntaxException {
00038         Function fun = null;
00039         decl.parse(source, lexer, declParser);
00040         if (decl.arity == DeclarationParser.UNKNOWN_ARITY) {
00041             try {
00042                 double value = eval(symbols, decl.expression);
00043                 fun = new Constant(value);
00044             } catch (SyntaxException e) {
00045                 if (e != SimpleCodeGen.HAS_ARGUMENTS) {
00046                     throw e;
00047                 }
00048                 // fall-through (see below)
00049             }
00050         }
00051                 
00052         if (fun == null) { // either decl.arity was set, or an ArityException happened above
00053             symbols.pushFrame();
00054             symbols.addArguments(decl.args);
00055             try {
00056                 rpn.setConsumer(codeGen.setSymbols(symbols));
00057                 lexer.scan(decl.expression, rpn);
00058             } finally {
00059                 symbols.popFrame();
00060             }
00061             int arity = decl.arity;
00062             if (arity == DeclarationParser.UNKNOWN_ARITY) {
00063                 arity = codeGen.intrinsicArity;
00064             }
00065             fun = codeGen.getFun(arity);
00066 
00067             /*
00068             if (decl.name != null && addDefinition) {
00069                 symbols.addDefinition(decl.name, fun, decl.arity==DeclarationParser.UNKNOWN_ARITY);
00070             }
00071             */
00072         }
00073 
00074         return new FunctionAndName(fun, decl.name);
00075     }
00076 }