001: /**************************************************************************/
002: /* N I C E */
003: /* A simple imperative object-oriented research language */
004: /* (c) Daniel Bonniot 2000 */
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.Procedure1;
014: import gnu.expr.*;
015: import gnu.bytecode.*;
016:
017: /**
018: Inlining of native unary boolean operators.
019:
020: @author Daniel Bonniot
021: */
022: public class BoolNotOp extends Procedure1 implements Inlineable,
023: Branchable {
024: private BoolNotOp() {
025: }
026:
027: public final static BoolNotOp instance = new BoolNotOp();
028:
029: public static BoolNotOp create(String param) {
030: return instance;
031: }
032:
033: public void compile(ApplyExp exp, Compilation comp, Target target) {
034: Expression[] args = exp.getArgs();
035: CodeAttr code = comp.getCode();
036: Target stack = new StackTarget(Type.boolean_type);
037: Branchable branchOp = args[0].getBranchable();
038: Label _else = new Label(code);
039: Label _end = new Label(code);
040:
041: if (branchOp != null) {
042: branchOp.compileJump(comp, ((ApplyExp) args[0]).getArgs(),
043: _else);
044: code.emitPushBoolean(true);
045: code.emitGoto(_end);
046: code.popType(); //simulate 'else' otherwise gnu.bytecode don't like it
047: _else.define(code);
048: code.emitPushBoolean(false);
049: _end.define(code);
050: } else {
051: args[0].compile(comp, stack);
052: code.emitPushConstant(1, Type.int_type);
053: code.emitXOr();
054: }
055: target.compileFromStack(comp, retType);
056: }
057:
058: public void compileJump(Compilation comp, Expression[] args,
059: Label to) {
060: CodeAttr code = comp.getCode();
061: Target stack = new StackTarget(Type.boolean_type);
062: Branchable branchOp = args[0].getBranchable();
063:
064: if (branchOp != null) {
065: branchOp.compileJumpNot(comp, ((ApplyExp) args[0])
066: .getArgs(), to);
067: } else {
068: args[0].compile(comp, stack);
069: code.emitGotoIfIntEqZero(to);
070: }
071: }
072:
073: public void compileJumpNot(Compilation comp, Expression[] args,
074: Label to) {
075: CodeAttr code = comp.getCode();
076: Target stack = new StackTarget(Type.boolean_type);
077: Branchable branchOp = args[0].getBranchable();
078:
079: if (branchOp != null) {
080: branchOp.compileJump(comp, ((ApplyExp) args[0]).getArgs(),
081: to);
082: } else {
083: args[0].compile(comp, stack);
084: code.emitGotoIfIntNeZero(to);
085: }
086:
087: }
088:
089: private static final Type retType = Type.boolean_type;
090:
091: public Type getReturnType(Expression[] args) {
092: return retType;
093: }
094:
095: // Interpretation
096:
097: public Object apply1(Object arg) {
098: throw new Error("Not implemented");
099: }
100: }
|