OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [AS64/] [source/] [expr128.cpp] - Rev 48

Compare with Previous | Blame | View Log

// ============================================================================
//        __
//   \\__/ o\    (C) 2014  Robert Finch, Stratford
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//
// A64 - Assembler
//  - 64 bit CPU
//
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
//                                                                          
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
// ============================================================================
//
#include "stdafx.h"
 
Int128 expr128();
extern int nsym;
 
// id
// const
// (expr)
// >expr
static Int128 primary()
{
    Int128 val;
    SYM *sym;
    static char buf[500];
 
    switch(token) {
    case tk_id:
         if (lastid[0]=='.')  // local label
            sprintf(buf, "%s%s", current_label, lastid);
         else
             strcpy(buf, lastid);
         sym = find_symbol(buf);
         if (!sym)
             sym = new_symbol(buf);
         val = sym->value;
         if (sym->segment < 5)
             nsym++;
         lastsym = sym;
         NextToken();
         if (token==tk_eol)
            prevToken();
         break;
    case tk_icon:
         val = ival;
         NextToken();
         if (token==tk_eol)
            prevToken();
         break;
    case '\'':
         inptr++;
		 if (*inptr=='\\') {
			 inptr++;
			 switch(*inptr) {
			 case '\r':	val.low = '\r'; val.high = 0; NextToken(); expect('\''); return (val);
			 case '\n':	val.low = '\n'; val.high = 0; NextToken(); expect('\''); return (val);
			 case '\t':	val.low = '\t'; val.high = 0; NextToken(); expect('\''); return (val);
			 case '\f':	val.low = '\f'; val.high = 0; NextToken(); expect('\''); return (val);
			 case '\b':	val.low = '\b'; val.high = 0; NextToken(); expect('\''); return (val);
			 }
		 }
         val.low = *inptr;
		 val.high = 0;
         NextToken();
         expect('\'');
         break;
    case '(':
         NextToken();
         val = expr128();
         expect(')');
         break;
    default:
       //printf("Syntax error.\r\n");
       val.low = val.high = 0;
       if (token != tk_eol)
           NextToken();
      break;
    }    
    return (val);
}
 
// !unary
// -unary
// +unary
// ~unary
//  primary
 
static Int128 unary()
{
    Int128 val;
 
    switch(token) {
    case '!':
		NextToken();
		val = unary();
		if (Int128::IsEqual(&val,Int128::Zero()))
			Int128::Assign(&val,Int128::One());
		else
			Int128::Assign(&val,Int128::Zero());
		return (val);
    case '-':
		NextToken();
		val = unary();
		Int128::Sub(&val,Int128::Zero(),&val);
		return (val);
    case '+':
		NextToken();
		val = unary();
		return (val);
    case '~':
		NextToken();
		val = unary();
		val.low = ~val.low;
		val.high = ~val.high;
		return (val);
    default:
        return (primary());
    }
}
 
// unary
// unary [*/%] unary
 
static Int128 mult_expr()
{
    Int128 val, a, rem;
 
    val = unary();
    while(1) {
        switch(token) {
        case '*':
			NextToken();
			a = unary();
			Int128::Mul(&val, &val, &a);
			break;
        case '/':
			NextToken();
			a = unary();
			Int128::Div(&val, &rem, &val, &a);
			break;
        case '%':
			NextToken();
			a = unary();
			Int128::Div(&rem, &val, &val, &a);
			break;
        default: goto j1;
        }
    }
j1:
    return (val);
}
 
// mult_expr
// mult_expr [+-] add_expr_list
//
static Int128 add_expr()
{
    Int128 val, a;
 
    val = mult_expr();
    while (1) {
        switch(token) {
        case '+':
			NextToken();
			a = mult_expr();
			Int128::Add(&val, &val, &a);
			break;
        case '-':
			NextToken();
			a = mult_expr();
			Int128::Sub(&val, &val, &a);
			break;
        default: goto j1;
        }
    }
j1:
    return (val);
}
 
static Int128 shift_expr()
{
    Int128 val, amt;
    int nn;
 
    val = add_expr();
    while(1) {
        switch(token) {
        case tk_lshift:
			NextToken();
			amt = add_expr();
			for (nn = 0; nn < 128 && nn < amt.low; nn++)
				Int128::Shl(&val, &val);
			break;
        case tk_rshift:
			NextToken();
			amt = add_expr();
			for (nn = 0; nn < 128 && nn < amt.low; nn++)
				Int128::Shr(&val, &val);
			break;
        default: goto j1;
        }
    }
j1:
    return (val);
}
 
static Int128 relational_expr()
{
    Int128 val, a;
 
    val = shift_expr();
    while (1) {
        switch(token) {
        case tk_lt:
			NextToken();
			a = shift_expr();
			if (Int128::IsLessThan(&val, &a))
				Int128::Assign(&val, Int128::One());
			else
				Int128::Assign(&val, Int128::Zero());
			break;
        case tk_le:
			NextToken();
			a = shift_expr();
			if (Int128::IsLessThan(&val, &a) || Int128::IsEqual(&val, &a))
				Int128::Assign(&val, Int128::One());
			else
				Int128::Assign(&val, Int128::Zero());
			break;
        case tk_gt:
			NextToken();
			a = shift_expr();
			if (!Int128::IsLessThan(&val, &a) && !Int128::IsEqual(&val, &a))
				Int128::Assign(&val, Int128::One());
			else
				Int128::Assign(&val, Int128::Zero());
			break;
        case tk_ge:
			NextToken();
			a = shift_expr();
			if (!Int128::IsLessThan(&val, &a) || Int128::IsEqual(&val, &a))
				Int128::Assign(&val, Int128::One());
			else
				Int128::Assign(&val, Int128::Zero());
			break;
        default: goto j1;
        }
    }
j1:
    return (val);
}
 
// relational_expr
// relational_expr & equals_expr_list
//
static Int128 equals_expr()
{
    Int128 val, a;
 
    val = relational_expr();
    while (1) {
        switch(token) {
		case tk_eq:
			NextToken();
			a = relational_expr();
			if (Int128::IsEqual(&val, &a))
				Int128::Assign(&val, Int128::One());
			else
				Int128::Assign(&val, Int128::Zero());
			break;
        case tk_ne:
			NextToken();
			a = relational_expr();
			if (!Int128::IsEqual(&val, &a))
				Int128::Assign(&val, Int128::One());
			else
				Int128::Assign(&val, Int128::Zero());
			break;
        default: goto j1;
        }
    }
j1:
    return (val);
}
 
// equals_expr
// equals_expr & bitwise_expr_list
//
static Int128 bitwise_expr()
{
    Int128 val, a;
 
    val = equals_expr();
    while (1) {
        switch(token) {
        case '&':
			NextToken();
			a = equals_expr();
			val.low = val.low & a.low;
			val.high = val.high & a.high;
			break;
        case '^':
			NextToken();
			a = equals_expr();
			val.low = val.low ^ a.low;
			val.high = val.high ^ a.high;
			break;
        case '|':
			NextToken();
			a = equals_expr();
			val.low = val.low | a.low;
			val.high = val.high | a.high;
			break;
        default: goto j1;
        }
    }
j1:
    return (val);
}
 
// bitwise_expr
// bitwise_expr && and_expr_list
//        
static Int128 and_expr()
{
    Int128 val, a;
 
    val = bitwise_expr();
    while(token==tk_land) {
        NextToken();
		a = bitwise_expr();
		if (Int128::IsEqual(&a,Int128::Zero()) || Int128::IsEqual(&val,Int128::Zero()))
			Int128::Assign(&val,Int128::Zero());
		else
			Int128::Assign(&val,Int128::One());
    }        
    return (val);
}
 
// and_expr
// and_expr || or_expr_list
//
static Int128 or_expr()
{
    Int128 val, a;
 
    val = and_expr();
    while(token==tk_lor) {
        NextToken(); 
		a = and_expr();
		if (!Int128::IsEqual(&a,Int128::Zero()) || !Int128::IsEqual(&val,Int128::Zero()))
			Int128::Assign(&val,Int128::One());
		else
			Int128::Assign(&val,Int128::Zero());
    }
    return (val);
}
 
Int128 expr128()
{
    Int128 val;
 
    nsym = 0;
    lastsym = (SYM*)NULL;    
    if (token=='#')
       NextToken();
    val = or_expr();
    // We only care about the symbol if relocatable output is being generated.
    // Setting the symbol to NULL will result in no rel records being output.
    if (nsym > 1 || !rel_out)
        lastsym = (SYM *)NULL;
    return val;
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.