001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2002 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package nice.lang.inline;
012:
013: import gnu.mapping.ProcedureN;
014: import gnu.expr.*;
015: import gnu.bytecode.*;
016:
017: /**
018: Test a boolean assertion, and raise an error if it is false.
019:
020: Do no throw a java.lang.AssertionError, since that class is only
021: available in JDK 1.4 and later. Instead throw a nice.lang.AssertionFailed.
022:
023: @version $Date: 2005/04/11 13:56:13 $
024: @author Daniel Bonniot (bonniot@users.sourceforge.net)
025: */
026:
027: public class Assert extends ProcedureN implements Inlineable {
028: public Assert(boolean assertEnableCheck) {
029: this .assertEnableCheck = assertEnableCheck;
030: }
031:
032: public static Assert create(String param) {
033: if (param == null)
034: return instance;
035: return contractInstance;
036: }
037:
038: private boolean assertEnableCheck;
039:
040: private static final Assert instance = new Assert(true);
041: private static final Assert contractInstance = new Assert(false);
042:
043: public void compile(ApplyExp exp, Compilation comp, Target target) {
044: Expression[] args = exp.getArgs();
045: CodeAttr code = comp.getCode();
046: Label end = new Label(code);
047:
048: if (this .assertEnableCheck && args[0] != QuoteExp.falseExp)
049: code.ifAssertionsDisabledGoto(((ClassExp) comp.topLambda)
050: .getAssertionEnabledField(), end);
051:
052: Branchable branchOp = args[0].getBranchable();
053: if (branchOp != null) {
054: branchOp.compileJump(comp, ((ApplyExp) args[0]).getArgs(),
055: end);
056: } else if (args[0] == QuoteExp.falseExp) {
057: //always continue to throwing exception
058: } else {
059: args[0].compile(comp, Type.boolean_type);
060: code.emitGotoIfIntNeZero(end); // The assertion is true.
061: }
062:
063: code.emitNew(errorClass);
064: code.emitDup();
065:
066: prepare();
067: if (args.length == 1) {
068: code.emitInvokeSpecial(errorInit);
069: } else {
070: args[1].compile(comp, Target.pushObject);
071: if (args[1].getType().getName().equals(
072: Type.string_type.getName())) {
073: code.emitInvokeSpecial(errorInitString);
074: } else {
075: code.emitInvokeVirtual(errorToString);
076: code.emitInvokeSpecial(errorInitString);
077: }
078: }
079:
080: code.emitThrow();
081: target.compileFromStack(comp, Type.void_type);
082:
083: end.define(code);
084: }
085:
086: private static final ClassType errorClass = ClassType
087: .make("nice.lang.AssertionFailed");
088:
089: private static Method errorInit, errorInitString, errorToString;
090:
091: private static void prepare() {
092: if (errorInit != null)
093: return;
094:
095: errorInit = errorClass.addMethod("<init>", Access.PUBLIC,
096: new Type[] {}, Type.void_type);
097: errorInitString = errorClass.addMethod("<init>", Access.PUBLIC,
098: new Type[] { Type.string_type }, Type.void_type);
099: errorToString = Type.pointer_type.addMethod("toString",
100: Access.PUBLIC, new Type[] {}, Type.string_type);
101: }
102:
103: public Type getReturnType(Expression[] args) {
104: return Type.void_type;
105: }
106:
107: // Interpretation
108:
109: public Object applyN(Object[] args) {
110: throw new Error("Not implemented");
111: }
112: }
|