Beispiel #1
0
void        testSymbol()
{
#if 0   // Operator
    int i = 0;
    for(; i < KeywordsCount; ++i)
    {
        printf("%s\n", Operators[i]);
    }
#endif
    
// test: isKeyword  isLiteral  isVar   isSemicolon  symbol_construct  symbol_deconstruct
#if 0   // not ok
    char *symbol[] = {"int", "i", "=", "12", ";"};
    for(int i = 0; i < sizeof(symbol) / sizeof(symbol[0]); ++i)
    {
        // ok
        printf("symbol %s : isKeyword:%s isLiteral:%s isVar:%s isSemicolon:%s\n", 
               symbol[i], TO_BOOL_STR(isKeyword(symbol[i])), TO_BOOL_STR(isLiteral(symbol[i])),
               TO_BOOL_STR(isVar(symbol[i])), TO_BOOL_STR(isSemicolon(symbol[i])));
        Symbol *sb = symbol_construct(symbol[i]);
        if(sb)
        {
            // not ok
            printf("%x %x %x %x \n",  IS_KEYWORD(sb->type), 
                                IS_LITERAL(sb->type), 
                                IS_VAR(sb->type),
                                IS_SEMICOLON(sb->type));
            symbol_deconstruct(sb);
        }
    }
#endif
    
// test: isCharLiteral isStringLiteral isDecNumber isOctNumber isHexNumber isFloatNumer
// tes:  isDoubleNumber
#if 0   // ok
    int i = 0;
    const char *strArr[] = {"\'c\'", "\"abc\"", "453", "0453", "781", "a90", "0x34", "0X56",
                            "9.34", "9.4e2", "9.5E5", "9e+2", "9e-3", "9.34f", "9.34F"
                            };

    for(; i < sizeof(strArr) / sizeof(strArr[0]); ++i)
    {
        printf("%s: isCharLiteral(%s)\n\t", strArr[i], TO_BOOL_STR(isCharLiteral(strArr[i])));
        printf("isStringLiteral(%s)\n\t", TO_BOOL_STR(isStringLiteral(strArr[i])));
        printf("isDecNumber(%s)\n\t", TO_BOOL_STR(isDecNumber(strArr[i])));
        printf("isOctNumber(%s)\n\t", TO_BOOL_STR(isOctNumber(strArr[i])));
        printf("isHexNumber(%s)\n\t", TO_BOOL_STR(isHexNumber(strArr[i])));
        printf("isFloatNumber(%s)\n\t", TO_BOOL_STR(isFloatNumber(strArr[i])));
        printf("isDoubleNumber(%s)\n", TO_BOOL_STR(isDoubleNumber(strArr[i])));
    }
    
    /*  // I don't know why, but it can't output all strings
    for(; i < sizeof(strArr) / sizeof(strArr[0]); ++i)
    {
        printf("%s: isCharLiteral(%s)\n\t isStringLiteral(%s)\n\t isDecNumber(%s)\n\t isOctNumber(%s)\n\t isHexNumber(%s)\n\t isFloatNumber(%s)\n\t isDoubleNumber(%s)\n",
               strArr[i], TO_BOOL_STR(isCharLiteral(strArr[i])), TO_BOOL_STR(isStringLiteral(strArr[i])), TO_BOOL_STR(isDecNumber(strArr[i])), TO_BOOL_STR(isOctNumber(strArr[i])), TO_BOOL_STR(isHexNumber(strArr[i])), TO_BOOL_STR(isFloatNumber(strArr[i])), TO_BOOL_STR(isDoubleNumber(strArr[i])));
    }
     */
#endif
}
Beispiel #2
0
static void
registerWakeup(Word name, Word value ARG_LD)
{ Word wake;
  Word tail = valTermRef(LD->attvar.tail);

  assert(gTop+6 <= gMax && tTop+4 <= tMax);

  wake = gTop;
  gTop += 4;
  wake[0] = FUNCTOR_wakeup3;
  wake[1] = needsRef(*name) ? makeRef(name) : *name;
  wake[2] = needsRef(*value) ? makeRef(value) : *value;
  wake[3] = ATOM_nil;

  if ( *tail )
  { Word t;				/* Non-empty list */

    deRef2(tail, t);
    TrailAssignment(t);
    *t = consPtr(wake, TAG_COMPOUND|STG_GLOBAL);
    TrailAssignment(tail);		/* on local stack! */
    *tail = makeRef(wake+3);
    DEBUG(1, Sdprintf("appended to wakeup\n"));
  } else				/* empty list */
  { Word head = valTermRef(LD->attvar.head);

    assert(isVar(*head));
    TrailAssignment(head);		/* See (*) */
    *head = consPtr(wake, TAG_COMPOUND|STG_GLOBAL);
    TrailAssignment(tail);
    *tail = makeRef(wake+3);
    LD->alerted |= ALERT_WAKEUP;
    DEBUG(1, Sdprintf("new wakeup\n"));
  }
}
Beispiel #3
0
Symbol      *symbol_construct(const char *str)
{
    SYMBOL_TYPE type;
    Symbol *sb = (Symbol *)malloc(sizeof(Symbol));
    if(!sb)
        return NULL;
    char *sbStr = (char *)malloc(strlen(str) + 1);
    if(!sbStr)
        return NULL;
    
    type = 0;
    if(isKeyword(str))
        type |= SYMBOL_TYPE_KEYWORD;
    if(isVar(str))
        type |= SYMBOL_TYPE_VAR;
    if(isSemicolon(str))
        type |= SYMBOL_TYPE_SEMICOLON;
    if(isLiteral(str))
        type |= SYMBOL_TYPE_LITERAL;
    sb->type = type;
    
    strcpy(sbStr, str);
    sb->str = sbStr;
    return sb;
}
Beispiel #4
0
/*
 * Copy an expression, but replace all occurences of a given variable with a
 * given expression.
 */
Exp *replace(Exp *body, int bind, Exp *arg) { // :-) YOU CAN DO IT!!!
    if(isApp(body)) {
        return newApp(replace(appFun(body), bind, arg),
                replace(appArg(body), bind, arg));
    }
    else if(isAbs(body)) {
        return newAbs(replace(absBody(body), bind + 1, arg));
    }
    else if(isVar(body)) {
        if(varBind(body) == bind) {
            return copyExp(arg);
        }
        else {
            return copyExp(body);
        }
    }
    else if(isCon(body) || isOpn(body)) {
        return copyExp(body);
    }
    else {
        printf("Error - unrecognised expression type in replace()\n");
        assert(false);
        return NULL;
    }
}
Beispiel #5
0
/*
 * Determine whether or not two expressions are equal.
 */
bool expEqual(Exp *e1, Exp *e2) {
    if(isApp(e1)) {
        if(!isApp(e2)) {
            return false;
        }
        else {
            return expEqual(appFun(e1), appFun(e2))
                && expEqual(appArg(e1), appArg(e2));
        }
    }
    else if(isAbs(e1)) {
        if(!isAbs(e2)) {
            return false;
        }
        else {
            return expEqual(absBody(e1), absBody(e2));
        }
    }
    else if(isVar(e1)) {
        if(!isVar(e2)) {
            return false;
        }
        else {
            return varBind(e1) == varBind(e2);
        }
    }
    else if(isCon(e1)) {
        if(!isCon(e2)) {
            return false;
        }
        else {
            return (conVal(e1) == conVal(e2)) && (conTy(e1) == conTy(e2));
        }
    }
    else if(isOpn(e1)) {
        if(!isOpn(e2)) {
            return false;
        }
        else {
            return opnType(e1) == opnType(e2);
        }
    }
    else {
        printf("Error - unrecognised expression type in expEqual()\n");
        assert(false);
    }
}
Beispiel #6
0
void
assignAttVar(Word av, Word value, int flags ARG_LD)
{ Word a;
  mark m;

  assert(isAttVar(*av));
  assert(!isRef(*value));
  assert(gTop+8 <= gMax && tTop+6 <= tMax);
  DEBUG(CHK_SECURE, assert(on_attvar_chain(av)));

  DEBUG(1, Sdprintf("assignAttVar(%s)\n", vName(av)));

  if ( isAttVar(*value) )
  { if ( value > av )
    { Word tmp = av;
      av = value;
      value = tmp;
    } else if ( av == value )
      return;
  }

  if( !(flags & ATT_ASSIGNONLY) )
  { a = valPAttVar(*av);
    registerWakeup(av, a, value PASS_LD);
  }

  if ( (flags&ATT_WAKEBINDS) )
    return;

  Mark(m);		/* must be trailed, even if above last choice */
  LD->mark_bar = NO_MARK_BAR;
  TrailAssignment(av);
  DiscardMark(m);

  if ( isAttVar(*value) )
  { DEBUG(1, Sdprintf("Unifying two attvars\n"));
    *av = makeRef(value);
  } else if ( isVar(*value) )
  { DEBUG(1, Sdprintf("Assigning attvar with plain var\n"));
    *av = makeRef(value);			/* JW: Does this happen? */
  } else
    *av = *value;

  return;
}
Beispiel #7
0
    void matchType() const {
        givenACodeSampleToTokenize type("abc", true);
        ASSERT_EQUALS(true, Token::Match(type.tokens(), "%type%"));

        givenACodeSampleToTokenize isVar("int a = 3 ;");
        ASSERT_EQUALS(true, Token::Match(isVar.tokens(), "%type%"));
        ASSERT_EQUALS(true, Token::Match(isVar.tokens(), "%type% %var%"));
        ASSERT_EQUALS(false, Token::Match(isVar.tokens(), "%type% %type%"));

        givenACodeSampleToTokenize noType1_cpp("delete", true, true);
        ASSERT_EQUALS(false, Token::Match(noType1_cpp.tokens(), "%type%"));

        givenACodeSampleToTokenize noType1_c("delete", true, false);
        ASSERT_EQUALS(true, Token::Match(noType1_c.tokens(), "%type%"));

        givenACodeSampleToTokenize noType2("void delete", true);
        ASSERT_EQUALS(false, Token::Match(noType2.tokens(), "!!foo %type%"));
    }
Beispiel #8
0
/*
 * Copy an expression, return a pointer to the newly allocated expression.
 */
Exp *copyExp(Exp *exp) {
    if(isApp(exp)) {
        return newApp(copyExp(appFun(exp)), copyExp(appArg(exp)));
    }
    else if(isAbs(exp)) {
        return newAbs(copyExp(absBody(exp)));
    }
    else if(isVar(exp)) {
        return newVar(varBind(exp));
    }
    else if(isCon(exp)) {
        return newCon(conTy(exp), conVal(exp));
    }
    else if(isOpn(exp)) {
        return newOpn(opnType(exp));
    }
    else {
        printf("Error - unrecognised expression type in copyExp()\n");
        assert(false);
    }
}
Beispiel #9
0
Token_type  
getTokenTypeByName(const char *name)
{
    if(isKeyword(name))
        return Token_type_keyword;
    if(isCharLiteral(name))
        return Token_type_literal;
    if(isStringLiteral(name))
        return Token_type_literal;
    if(isVar(name))
        return Token_type_var;
    if(isOperator(name))
        return Token_type_operator;
    if(isDecNumber(name) 
    || isHexNumber(name) 
    || isOctNumber(name)
    || isFloatNumber(name)
    || isDoubleNumber(name))
        return Token_type_num;
    if(isSemicolon(name))
        return Token_type_semicolon;
    
    return Token_type_err;
}
Beispiel #10
0
/* ------------------------------------------------------------------------------------------ */
void checkInstruction(ins *p){
	reg *rz=NULL;
	reg *rx=NULL;
	reg *ry=NULL;
	reg *rt=NULL;	// temporary register (may or not be used)
	ins *ip=NULL;	// auxiliary instruction pointer (for other registers)
	ins *ti=NULL;	// temporary instruction pointer (to be used with the temporary register)
	ins *mi=NULL;	// main instruction pointer (used with the final instruction)


	/*
	 *  >> input: rz = rx <op> ry
	 *
	 *
	 *	rx = ARP + lookup(rx->value)
	 *    	rx = * rx
	 *    	ry = ARP + lookup(ry->value)
	 *    	ry = * ry
	 *    	rt = rx <op> ry
	 *    	rz = ARP + lookup(rz->value)
	 *	*rz = rt
	 */


	if(p == NULL)
		return;

	#ifdef VERBOSE
		printf("\n");
		table_print(registers);
		printf("[checkInstruction] ");
		printInstruction(p);
	#endif



// :: -------------------------------- ::   THE ALGORITHM   ::

// 1st step:  ensure that 'rx' and 'ry' have register
// --

	// checking 'rx'
	if((p->src1[0] != '\0') && !isNumeric(p->src1)){
		rx=reg_search(p->src1);
		if(rx==NULL){
	
			// allocates register
			rx=reg_ensure(p->src1);
			if(isVar(p->src1)){
				
				// loading the local variable from memory
				load(p->src1);
				
				ip = createInstruction(idx++);
				copy(ip->dst, rx->name);
				ip->arp=true;
				ip->offset=lookup(p->src1);
				append(ip);

				ip = createInstruction(idx++);
				copy(ip->dst, rx->name);
				ip->ops1='*';
				copy(ip->src1, rx->name);
				append(ip);
			}
			if(rx!=NULL){
				// set properties for register
				rx->dist=distance(p, rx->value);
				rx->dirty=false;
			}
		}
	} else rx=NULL;

	// checking 'ry'
	if((p->src2[0] != '\0') && !isNumeric(p->src2)){
		ry=reg_search(p->src2);
		if(ry==NULL){

			// allocates register
			ry=reg_ensure(p->src2);
			if(isVar(p->src2)){
				
				// loading the local variable 'ry' from memory
				load(p->src2);
				
				// loading the local variable 'ry' from memory
				ip = createInstruction(idx++);
				copy(ip->dst, ry->name);
				ip->arp=true;
				ip->offset=lookup(p->src2);
				append(ip);
	
				ip = createInstruction(idx++);
				copy(ip->dst, ry->name);
				ip->ops1='*';
				copy(ip->src1, ry->name);
				append(ip);
			}
			if(ry!=NULL){
				// set properties for register
				ry->dist=distance(p, ry->value);
				ry->dirty=true;
			}
		}
	} else ry=NULL;

// 2nd step: allocate the 'rt' temporary register; creates the 'ti' temporary instruction
// --

	ti = createInstruction(idx++);

	// get 'rx'
	if(isNumeric(p->src1))
		copy(ti->src1, p->src1);  // found a constant
	else if(rx!=NULL)
		copy(ti->src1, rx->name); // got the 'rx'

	// get the operator
	ti->ops2=p->ops2;

	// get 'ry'
	if(isNumeric(p->src2))
		copy(ti->src2, p->src2);  // found a constant
	else if(ry!=NULL)
		copy(ti->src2, ry->name); // got the 'ry'

	if((p->dst[0] != '\0') && !isNumeric(p->dst)){

		// allocate the 'rt' register ("r0" by default)
		rt=reg_search("store");
//		rt=reg_get();
		if(rt!=NULL)
			rt->dirty=false;
	} else rt=NULL; // this could lead to an error
	if(rt!=NULL)
		copy(ti->dst, rt->name);

	append(ti);

// 3rd step: frees if possible frees 'rx' and 'ry'
// --

	// free 'rx'
	if((rx!=NULL) && (rx->dist==MAXDIST || rx->dist==-2))
		reg_free(rx);
	// free 'ry'
	if((ry!=NULL) && (ry->dist==MAXDIST || ry->dist==-2))
		reg_free(ry);

// 4th step: allocate the 'rz' register and create the main instruction 'mi'
// --

	mi = createInstruction(idx++);

	// allocate the 'rz' register
	if((p->dst[0] != '\0') && !isNumeric(p->dst)){

		// store
		store(p->dst);
		rz=reg_search(p->dst);
		if(rz==NULL){
			
			// allocates register
			rz=reg_ensure(p->dst);

			if(isVar(p->dst)){
				// loads the local variable for store operation
				ip = createInstruction(idx++);
				copy(ip->dst, rz->name);
				ip->arp=true;
				ip->offset=lookup(p->dst);
				append(ip);
			}
			if(rz!=NULL){
				// set properties for register
				rz->dist=distance(p, rz->value);
				rz->dirty=false;
			}
		}
	} else rz=NULL; // this would be an error
	if(rz!=NULL)
		copy(mi->dst, rz->name);
	if(rt!=NULL)
		copy(mi->src1, rt->name);
	if(isVar(p->dst))
		mi->opd='*';
	append(mi);


// 5th step: frees 'rt'; if possible frees 'rz'
// --

	#ifdef VERBOSE
		if(rt!=NULL) printf(" [rt] store: %s :: (%s)\n", rt->name, rt->value);
		else printf(" [rt] is null\n");
		if(rz!=NULL) printf(" [rz] store: %s :: (%s)\n", rz->name, rz->value);
		else printf(" [rz] is null\n");
	#endif
	// free 'rt'
	if(rt!=NULL) reg_free(rt);
	// free 'rz'
	if((rz!=NULL) && (rz->dist==MAXDIST || rz->dist<0))
		reg_free(rz);

// 6th step: set the dirty property for the registers
// --
	// check 'rx'
	if(rx!=NULL)
		rx->dirty=true;
	// check 'ry'
	if(ry!=NULL)
		ry->dirty=true;
	// check 'rt'
	if(rt!=NULL)
		rt->dirty=true;
	// check 'rz'
	if(rz!=NULL)
		rz->dirty=false;

// nota: um registo e' dirty apenas quando o seu conteudo e' manipulado na memoria !!!!
//      (confirmar e corrigir se necessario o 6o passo)
//      mudar os valores de dirty para oposto:  'false' <-> 'true'

// :: -------------------------------- ::   THE END   ::

	#ifdef VERBOSE
		table_print(registers);
		printf("\n");
	#endif
	return;
}
Beispiel #11
0
/*
 * Perform at least one reduction step on the given template.
 */
Exp *reduceTemplate(Exp *exp) {

    // Conditionals
    if(isApp(exp)
            && isApp(appFun(exp))
            && isApp(appFun(appFun(exp)))
            && isOpn(appFun(appFun(appFun(exp))))
            && (opnType(appFun(appFun(appFun(exp)))) == O_Cond)) {

        Exp *guard  = appArg(appFun(appFun(exp)));
        Exp *truExp = appArg(appFun(exp));
        Exp *falExp = appArg(exp);

        // If the guard is true, return the true expression.
        if(isCon(guard) && (conVal(guard) == true)) {
            return copyExp(truExp);
        }
        // If the guard is false, return the false expression.
        else if(isCon(guard) && (conVal(guard) == false)) {
            return copyExp(falExp);
        }
        // If the guard is not reduced, reduce it.
        else {
            return newApp(newApp(newApp(
                            newOpn(O_Cond), reduceTemplate(guard)),
                        copyExp(truExp)), copyExp(falExp));
        }
    }
    // End of conditional case

    // Binary operations
    else if(isApp(exp)
            && isApp(appFun(exp))
            && isBinaryOpn(appFun(appFun(exp)))) {

        OpTy opn  = opnType(appFun(appFun(exp)));
        Exp *arg1 = appArg(appFun(exp));
        Exp *arg2 = appArg(exp);

        // Handle equality differently because it is polymorphic.
        if(opn == O_Equ) {
            Exp *redA1 = reduceTemplateNorm(arg1);
            Exp *redA2 = reduceTemplateNorm(arg2);
            bool same = expEqual(redA1, redA2);
            freeExp(redA1);
            freeExp(redA2);
            return newCon(C_Bool, same);
        }
        else if(isApp(arg1) || isAbs(arg1) || isVar(arg1) || isOpn(arg1)) {
            return newApp(
                    newApp(
                        newOpn(opn),
                        reduceTemplate(arg1)),
                    copyExp(arg2));
        }
        else if(isApp(arg2) || isAbs(arg2) || isVar(arg2) || isOpn(arg2)) {
            return newApp(
                    newApp(
                        newOpn(opn),
                        copyExp(arg1)),
                    reduceTemplate(arg2));
        }
        else {
            assert(isCon(arg1));
            assert(isCon(arg2));

            if(opn == O_Add) {
                return newCon(C_Int, conVal(arg1) + conVal(arg2));
            }
            else if(opn == O_Sub) {
                return newCon(C_Int, conVal(arg1) - conVal(arg2));
            }
            else if(opn == O_Mul) {
                return newCon(C_Int, conVal(arg1) * conVal(arg2));
            }
            else if(opn == O_Div) {
                return newCon(C_Int, conVal(arg1) / conVal(arg2));
            }
            else if(opn == O_Mod) {
                return newCon(C_Int, conVal(arg1) % conVal(arg2));
            }
            else if(opn == O_Lss) {
                return newCon(C_Bool, conVal(arg1) < conVal(arg2));
            }
            else if(opn == O_LsE) {
                return newCon(C_Bool, conVal(arg1) <= conVal(arg2));
            }
            else if(opn == O_NEq) {
                return newCon(C_Bool, conVal(arg1) != conVal(arg2));
            }
            else if(opn == O_Gtr) {
                return newCon(C_Bool, conVal(arg1) > conVal(arg2));
            }
            else if(opn == O_GtE) {
                return newCon(C_Bool, conVal(arg1) >= conVal(arg2));
            }
            else if(opn == O_Xor) {
                return newCon(C_Bool, (!conVal(arg1)) != (!conVal(arg2)));
            }
            else if(opn == O_And) {
                return newCon(C_Bool, conVal(arg1) && conVal(arg2));
            }
            else if(opn == O_Or ) {
                return newCon(C_Bool, conVal(arg1) || conVal(arg2));
            }
            else {
                printf("Error reducing binary operation - unrecognised "
                        "operation\n");
                assert(false);
            }
        }
    }
    // End of binary operations case

    // iszero & not unary operations
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && (opnType(appFun(exp)) == O_Not
            || opnType(appFun(exp)) == O_IsZ)) {

        OpTy opn = opnType(appFun(exp));
        Exp *arg = appArg(exp);

        if(isApp(arg) || isAbs(arg) || isVar(arg) || isOpn(arg)) {
            return newApp(newOpn(opn), reduceTemplate(arg));
        }
        else {
            if(opn == O_Not)  {
                return newCon(C_Bool, !(conVal(arg)));
            }
            else {
                assert(opn == O_IsZ);
                return newCon(C_Bool, conVal(arg) == 0);
            }
        }
    }
    // End iszero & not unary operations case

    // Polymorphic unary operations
    // Null
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && (opnType(appFun(exp)) == O_Null)) {

        Exp *arg = appArg(exp);
        Exp *reducedArg = reduceTemplateNorm(arg);

        if(isOpn(reducedArg) && (opnType(reducedArg) == O_Empty)) {
            freeExp(reducedArg);
            return newCon(C_Bool, true);
        }
        else {
            freeExp(reducedArg);
            return newCon(C_Bool, false);
        }
    }
    // End Null

    // Head and Tail
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && ((opnType(appFun(exp)) == O_Head)
            || (opnType(appFun(exp)) == O_Tail))) {

        OpTy opn = opnType(appFun(exp));
        Exp *arg = appArg(exp);

        if(isApp(arg)
                && isApp(appFun(arg))
                && isOpn(appFun(appFun(arg)))
                && (opnType(appFun(appFun(arg)))) == O_Cons) {
            
            Exp *head = appArg(appFun(arg));
            Exp *tail = appArg(arg);

            if(opn == O_Head) {
                return copyExp(head);
            }
            else {
                assert(opn == O_Tail);
                return copyExp(tail);
            }
        }
        else {
            return newApp(newOpn(opn), reduceTemplate(arg));
        }
    }
    // End Head and Tail

    // Cons
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && (opnType(appFun(exp)) == O_Cons)) {

        Exp *consArg = appArg(exp);

        return newApp(newOpn(O_Cons), reduceTemplate(consArg));
    }
    // End Cons
    
    // Sum operations
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && ((opnType(appFun(exp)) == O_RemL)
            || (opnType(appFun(exp)) == O_RemR))) {

        OpTy opn = opnType(appFun(exp));
        Exp *arg = appArg(exp);

        if(isApp(arg)
                && isOpn(appFun(arg))
                && ((opnType(appFun(arg)) == O_InjL)
                || (opnType(appFun(arg)) == O_InjR))) {

            OpTy innerOpn = opnType(appFun(arg));
            Exp *innerArg = appArg(arg);

            if(((opn == O_RemL) && (innerOpn == O_InjL))
                    || ((opn == O_RemR) && (innerOpn == O_InjR))) {
                
                return copyExp(innerArg);
            }
            else {
                printf("Error - removed value from a non-sum expression or "
                        "wrong side of sum expression\n");
                assert(false);
            }
        }
        else {
            return newApp(newOpn(opn), reduceTemplate(arg));
        }
    }
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && ((opnType(appFun(exp)) == O_InjL)
            || (opnType(appFun(exp)) == O_InjR))) {

        OpTy opn = opnType(appFun(exp));
        Exp *arg = appArg(exp);

        return newApp(newOpn(opn), reduceTemplate(arg));
    }
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && (opnType(appFun(exp)) == O_IsLeft)) {

        Exp *arg = appArg(exp);

        if(isApp(arg)
                && isOpn(appFun(arg))
                && ((opnType(appFun(arg)) == O_InjL)
                || (opnType(appFun(arg)) == O_InjR))) {

            OpTy injOpn = opnType(appFun(arg));
            return newCon(C_Bool, injOpn == O_InjL);
        }
        else {
            return newApp(newOpn(O_IsLeft), reduceTemplate(arg));
        }
    }
    // End sum operations
    
    // Tuple operations
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && ((opnType(appFun(exp)) == O_Fst)
            || (opnType(appFun(exp)) == O_Snd))) {

        OpTy opn = opnType(appFun(exp));
        Exp *arg = appArg(exp);

        if(isApp(arg)
                && isApp(appFun(arg))
                && isOpn(appFun(appFun(arg)))
                && (opnType(appFun(appFun(arg))) == O_Tuple)) {

            Exp *fst = appArg(appFun(arg));
            Exp *snd = appArg(arg);

            return copyExp((opn == O_Fst) ? fst : snd);
        }
        else {
            return newApp(newOpn(opn), reduceTemplate(arg));
        }
    }
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && (opnType(appFun(exp)) == O_Tuple)) {

        Exp *arg = appArg(exp);

        return newApp(newOpn(O_Tuple), reduceTemplate(arg));
    }
    // End Tuple operations

    // Fixed point combinator
    else if(isApp(exp)
            && isOpn(appFun(exp))
            && (opnType(appFun(exp)) == O_Fix)) {

        return newApp(copyExp(appArg(exp)), copyExp(exp));
    }
    // End fixed point combinator
    // End polymorphic unary operations

    // Lambda abstractions
    else if(isApp(exp)
            && isAbs(appFun(exp))) {

        Exp *abs = appFun(exp);
        Exp *arg = appArg(exp);

        return replace(absBody(abs), 0, arg);
    }
    // End lambda abstractions

    // Function calls
    else if(isApp(exp)
            && isVar(appFun(exp))) {

        Exp *var = appFun(exp);
        Exp *arg = appArg(exp);
        int bind = varBind(var);

        if(hasFunc(bind)) {
            return newApp(instantiate(bind), copyExp(arg));
        }
        else {
            return newApp(copyExp(var), reduceTemplate(arg));
        }
    }
    else if(isVar(exp)
            && hasFunc(varBind(exp))) {

        return instantiate(varBind(exp));
    }
    // End function calls

    // Catch-all application case
    else if(isApp(exp)) {
        Exp *fun = appFun(exp);
        Exp *arg = appArg(exp);

        return newApp(reduceTemplate(fun), reduceTemplate(arg));
    }
    // End catch-all application case

    // If there are no reductions to make, return a copy of the given template.
    else {
        return copyExp(exp);
    }
}
Beispiel #12
0
bool isSimple(Obj expr) { return isVar(expr) || isNum(expr); }
Beispiel #13
0
void assembleTo(FILE *fOut, FILE *fIn) {
    char cmd[lineLim+1], arg[argLim+1];
    int argI;

    while( getCmd(cmd,arg, fIn) && *cmd ) {
        if( *cmd == '$' ) regVar(cmd+1, arg);
        if( strchr(";:.$", *cmd) ) continue;

#define case_cmd(nam) !strcmp(cmd, #nam)? cmd_##nam
        fputc(
            case_cmd(jmp): case_cmd(jmpImm): case_cmd(jfImm):
            case_cmd(call): case_cmd(callImm): case_cmd(ret):

            case_cmd(putchar): case_cmd(getchar):
            case_cmd(write): case_cmd(readln):
            case_cmd(putStack): case_cmd(atEof):

            case_cmd(argc): case_cmd(argv):

            case_cmd(pushInt): case_cmd(pushChr): case_cmd(pushStr):
            case_cmd(pushVarInt): case_cmd(pushVarChr): case_cmd(pushVarStr):
            case_cmd(popInt): case_cmd(popChr): case_cmd(popStr):

            case_cmd(intToChr): case_cmd(intToStr):
            case_cmd(strToInt): case_cmd(strToChr):
            case_cmd(chrToInt): case_cmd(chrToStr):

            case_cmd(add): case_cmd(sub):
            case_cmd(mul): case_cmd(div): case_cmd(mod):
            case_cmd(eq): case_cmd(gt): case_cmd(lt):

            case_cmd(strcatChr): case_cmd(strcat):
            case_cmd(strlen):
            case_cmd(streq): case_cmd(strcmp):
            case_cmd(strmask):
            case_cmd(indexOf):
            case_cmd(replaceChr): case_cmd(setChr):
            case_cmd(chrAt):
            case_cmd(strdivInt): case_cmd(strdivChr):

            case_cmd(dupInt): case_cmd(swapInt): case_cmd(rotInt):
            case_cmd(dupChr): case_cmd(swapChr): case_cmd(rotChr):
            case_cmd(dupStr): case_cmd(swapStr): case_cmd(rotStr):
            cmd_stop
            ,
            fOut
        );
#undef case_cmd

        argI =
            *arg=='\''? arg[1]:
            *arg=='+'? idx+atoi(arg+1):
            *arg=='-'? idx-atoi(arg+1):
            *arg==':' || *arg=='.'? getLabel(fIn, arg):
            isdigit(*arg)? atoi(arg):
            isVar(arg)? varIdx(arg)+1:
            0;

        fputc(argI & 0xFF, fOut);
        fputc((argI >> 8) & 0xFF, fOut);
        ++idx;
    }
}
Beispiel #14
0
value caml_isVar(value e)
{
  CAMLparam1(e);
  CAMLreturn(Val_int(isVar(Expr_val(e))));
}
void ATMSP<T>::factor(ATMSB<T> &bc) {

	/// Check available memory
	if ( numInd>=ATMSP_MAXNUM || valInd>=ATMSP_SIZE || opCnt>=ATMSP_SIZE ) longjmp(errJmp, memErr);

	/// Handle open parenthesis and unary operators first
	if ( *cp == '(' ) {
		++cp; expression(bc);
		if ( *cp++ != ')' ) longjmp(errJmp, parErr);
	}
	else if ( *cp == '+' ) {
		++cp; factor(bc);
	}
	else if ( *cp == '-' ) {
		++cp; factor(bc);
		bc.fun[opCnt++] = &ATMSB<T>::pchs;
	}

	/// Extract numbers starting with digit or dot
	else if ( isdigit(*cp) || *cp=='.' ) {
		char *end;
		bc.num[numInd] = (T)strtod(cp, &end);
		bc.val[valInd++] = &bc.num[numInd++];
		bc.fun[opCnt++] = &ATMSB<T>::ppush;
		cp = end;
	}

	/// Extract constants starting with $
	else if ( *cp == '$' ) {
		if ( !conLst.find(skipAlphaNum(), conInd) ) longjmp(errJmp, conErr);
		bc.con[conInd] = conLst[conInd].val;
		bc.val[valInd++] = &bc.con[conInd];
		bc.fun[opCnt++] = &ATMSB<T>::ppush;
	}

	/// Extract variables
	else if ( isVar(cp) ) {
		if ( varLst.find(skipAlphaNum(), varInd) ) varCnt++; else longjmp(errJmp, varErr);
		bc.val[valInd++] = &bc.var[varInd];
		bc.fun[opCnt++] = &ATMSB<T>::ppush;
	}

	/// Extract functions
	else {

		// Search function and advance cp behind open parenthesis
		if ( funLst.find(skipAlphaNum(), funInd) ) ++cp; else longjmp(errJmp, funErr);

		// Set operator function and advance cp
		switch ( funInd ) {
			case  0: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pabs;    break;
			case  1: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pcos;    break;
			case  2: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pcosh;   break;
			case  3: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pexp;    break;
			case  4: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::plog;    break;
			case  5: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::plog10;  break;
			case  6: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::plog2;   break;
			case  7: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::psin;    break;
			case  8: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::psinh;   break;
			case  9: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::psqrt;   break;
			case 10: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::ptan;    break;
			case 11: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::ptanh;   break;
			#if !defined(COMPLEX)
			case 12: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pasin;   break;
			case 13: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pacos;   break;
			case 14: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::patan;   break;
			case 15: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::patan2;  break;
			case 16: expression(bc); ++cp; expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pmax; break;
			case 17: expression(bc); ++cp; expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pmin; break;
			case 18: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::psig;    break;
			case 19: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pfloor;  break;
			case 20: expression(bc); bc.fun[opCnt++] = &ATMSB<T>::pround;  break;
			#endif
		}
		++cp;
	}

	/// At last handle univalent operators like ^ or % (not implemented here)
	if ( *cp == '^' ) {

		// Exponent a positive number? Try to optimize later
		bool optPow = isdigit( *++cp ) ? true : false;
		if ( *(cp+1) == '^' ) optPow = false;
		factor(bc);

		// Speed up bytecode for 2^2, x^3 ...
		if ( optPow ) {
			if ( *bc.val[valInd-1] == (T)2.0 ) {
				--valInd;
				bc.fun[opCnt-1] = &ATMSB<T>::ppow2;
			}
			else if ( *bc.val[valInd-1] == (T)3.0 ) {
				--valInd;
				bc.fun[opCnt-1] = &ATMSB<T>::ppow3;
			}
			else if ( *bc.val[valInd-1] == (T)4.0 ) {
				--valInd;
				bc.fun[opCnt-1] = &ATMSB<T>::ppow4;
			}
			// Exponent is a positive number, but not 2-4. Proceed with standard pow()
			else
				bc.fun[opCnt++] = &ATMSB<T>::ppow;
		}
		// Exponent is a not a number or negative. Proceed with standard pow()
		else
			bc.fun[opCnt++] = &ATMSB<T>::ppow;
	}

} // End of factor(bc)
Beispiel #16
0
//----------------------------------------------------------------------
static int LoadArg(op_t &x)
{
  dref_t xreftype;
  switch ( x.type ) {
  case o_reg:
    {
      if ( x.reg == R_sp ) goto Undefined;
//      AbstractRegister *in = &i5_getreg(x.reg);
//      if ( ! in->isDef() ) goto Undefined;
//      r.doInt(in->value());
      return 1;
    }
  case o_imm:
//    r.doInt(unsigned(x.value));
    xreftype = dr_O;
MakeImm:
    doImmdValue(x.n);
    if ( isOff(uFlag, x.n) )
      ua_add_off_drefs2(x, xreftype, 0);
    return 1;
  case o_displ:
//    r.undef();
    xreftype = dr_R;
    goto MakeImm;
  case o_mem:
    {
      ea_t ea = toEA(dataSeg_op(x.n),x.addr);
      ua_add_dref(x.offb,ea,dr_R);
      ua_dodata2(x.offb, ea, x.dtyp);
      if ( !isVar(get_flags_novalue(ea)) && isLoaded(ea) )
      {
//        r.doInt( x.dtyp != dt_byte ? get_word(ea) : char(get_byte(ea)) );
        return 1;
      }
    }
  case o_phrase:
Undefined:
//    r.undef();
    break;

  case o_near:
    {
      ea_t segbase = codeSeg(x.addr,x.n);
      ea_t ea = toEA(segbase,x.addr);
      ea_t thisseg = cmd.cs;
      int iscall = InstrIsSet(cmd.itype,CF_CALL);
      ua_add_cref(x.offb,
                  ea,
                  iscall ? ((segbase == thisseg) ? fl_CN : fl_CF)
                         : ((segbase == thisseg) ? fl_JN : fl_JF));
      if ( iscall && !func_does_return(ea) )
        flow = false;
//      r.doInt(unsigned(x.addr));
    }
    return 1;
  default:
//  warning("%a: %s,%d: bad load optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
    break;
  }
  return 0;
}
Beispiel #17
0
/*
 * Print an expression to stdout.
 */
void printExp(Exp *exp) {
    if(isApp(exp)) {
        printf("(");
        printExp(appFun(exp));
        printf(" ");
        printExp(appArg(exp));
        printf(")");
    }
    else if(isAbs(exp)) {
        printf("(\\ ");
        printExp(absBody(exp));
        printf(")");
    }
    else if(isVar(exp)) {
        if(varBind(exp) >= 0) {
            printf("V%d", varBind(exp));
        }
        else {
            printf("F%d", -varBind(exp));
        }
    }
    else if(isCon(exp) && (conTy(exp) == C_Bool) && (conVal(exp) == true)) {
        printf("true");
    }
    else if(isCon(exp) && (conTy(exp) == C_Bool) && (conVal(exp) == false)) {
        printf("false");
    }
    else if(isCon(exp) && (conTy(exp) == C_Char)) {
        printf("\'%c\'", conVal(exp));
    }
    else if(isCon(exp)/* && (conTy(exp) == C_Int)*/) {
        printf("%d", conVal(exp));
    }
    else if(isOpn(exp)) {
        switch(opnType(exp)) {
            case O_Cond   : printf("cond")   ;  break;
            case O_Add    : printf("+")      ;  break;
            case O_Sub    : printf("-")      ;  break;
            case O_Mul    : printf("*")      ;  break;
            case O_Div    : printf("/")      ;  break;
            case O_Mod    : printf("%%")     ;  break;
            case O_Lss    : printf("<")      ;  break;
            case O_LsE    : printf("<=")     ;  break;
            case O_NEq    : printf("/=")     ;  break;
            case O_Gtr    : printf(">")      ;  break;
            case O_GtE    : printf(">=")     ;  break;
            case O_Equ    : printf("==")     ;  break;
            case O_And    : printf("and")    ;  break;
            case O_Or     : printf("or")     ;  break;
            case O_Xor    : printf("xor")    ;  break;
            case O_Not    : printf("not")    ;  break;
            case O_IsZ    : printf("iszero") ;  break;
            case O_Empty  : printf("[]")     ;  break;
            case O_Cons   : printf(":")      ;  break;
            case O_Null   : printf("null")   ;  break;
            case O_Head   : printf("head")   ;  break;
            case O_Tail   : printf("tail")   ;  break;
            case O_Fix    : printf("fix")    ;  break;
            case O_InjL   : printf("injl")   ;  break;
            case O_InjR   : printf("injr")   ;  break;
            case O_RemL   : printf("reml")   ;  break;
            case O_RemR   : printf("remr")   ;  break;
            case O_IsLeft : printf("isleft") ;  break;
            case O_Tuple  : printf("tuple")  ;  break;
            case O_Fst    : printf("fst")    ;  break;
            case O_Snd    : printf("snd")    ;  break;
        }
    }
    else {
        printf("Error - unrecognised expression type in printExp()\n");
        assert(false);
    }
}