Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***********************************************************************
  2.  *
  3.  *  avra - Assembler for the Atmel AVR microcontroller series
  4.  *
  5.  *  Copyright (C) 1998-2004 Jon Anders Haugum, Tobias Weber
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; see the file COPYING.  If not, write to
  19.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  *  Boston, MA 02111-1307, USA.
  21.  *
  22.  *
  23.  *  Authors of avra can be reached at:
  24.  *     email: jonah@omegav.ntnu.no, tobiw@suprafluid.com
  25.  *     www: http://sourceforge.net/projects/avra
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32.  
  33. #include "misc.h"
  34. #include "avra.h"
  35. #include "device.h"
  36.  
  37. #define IS_UNARY(x) ((x == '!') || (x == '-') || (x == '~'))
  38. #define IS_OPERATOR(x) ((x == '+') || (x == '-') || (x == '*') || (x == '/') || (x == '%') || (x == '<') || (x == '>') || (x == '=') || (x == '!') || (x == '&') || (x == '^') || (x == '|'))
  39. #define IS_2ND_OPERATOR(x) ((x == '<') || (x == '>') || (x == '=') || (x == '&') || (x == '|'))
  40.  
  41. enum {
  42.         OPERATOR_ERROR = 0,
  43.         OPERATOR_MUL,
  44.         OPERATOR_DIV,
  45.         OPERATOR_MOD,
  46.         OPERATOR_ADD,
  47.         OPERATOR_SUB,
  48.         OPERATOR_SHIFT_LEFT,
  49.         OPERATOR_SHIFT_RIGHT,
  50.         OPERATOR_LESS_THAN,
  51.         OPERATOR_LESS_OR_EQUAL,
  52.         OPERATOR_GREATER_THAN,
  53.         OPERATOR_GREATER_OR_EQUAL,
  54.         OPERATOR_EQUAL,
  55.         OPERATOR_NOT_EQUAL,
  56.         OPERATOR_BITWISE_AND,
  57.         OPERATOR_BITWISE_XOR,
  58.         OPERATOR_BITWISE_OR,
  59.         OPERATOR_LOGICAL_AND,
  60.         OPERATOR_LOGICAL_OR
  61.         };
  62.  
  63. enum {
  64.         FUNCTION_LOW = 0,
  65.         FUNCTION_BYTE1,
  66.         FUNCTION_HIGH,
  67.         FUNCTION_BYTE2,
  68.         FUNCTION_BYTE3,
  69.         FUNCTION_BYTE4,
  70.         FUNCTION_LWRD,
  71.         FUNCTION_HWRD,
  72.         FUNCTION_PAGE,
  73.         FUNCTION_EXP2,
  74.         FUNCTION_LOG2,
  75.         FUNCTION_COUNT
  76. };
  77.  
  78. struct element
  79.         {
  80.         struct element *next;
  81.         int data;
  82.         };
  83.  
  84. char *function_list[] = {
  85.     /*
  86.     ** allow whitespace between function name
  87.     ** and opening brace...
  88.     */
  89.         "low",
  90.         "byte1",
  91.         "high",
  92.         "byte2",
  93.         "byte3",
  94.         "byte4",
  95.         "lwrd",
  96.         "hwrd",
  97.         "page",
  98.         "exp2",
  99.         "log2"
  100. };
  101.  
  102. int log_2(int value)
  103. {
  104.   int i = 0;
  105.   while(value >>= 1)
  106.     i++;
  107.   return(i);
  108. }
  109.  
  110. int get_operator(char *op)
  111. {
  112.         switch(op[0]) {
  113.                 case '*':
  114.                         return(OPERATOR_MUL);
  115.                 case '/':
  116.                         return(OPERATOR_DIV);
  117.                 case '%':
  118.                         return(OPERATOR_MOD);
  119.                 case '+':
  120.                         return(OPERATOR_ADD);
  121.                 case '-':
  122.                         return(OPERATOR_SUB);
  123.                 case '<':
  124.                         switch(op[1]) {
  125.                                 case '<':
  126.                                         return(OPERATOR_SHIFT_LEFT);
  127.                                 case '=':
  128.                                         return(OPERATOR_LESS_OR_EQUAL);
  129.                                 default:
  130.                                         return(OPERATOR_LESS_THAN);
  131.                         }
  132.                 case '>':
  133.                         switch(op[1]) {
  134.                                 case '>':
  135.                                         return(OPERATOR_SHIFT_RIGHT);
  136.                                 case '=':
  137.                                         return(OPERATOR_GREATER_OR_EQUAL);
  138.                                 default:
  139.                                         return(OPERATOR_GREATER_THAN);
  140.                         }
  141.                 case '=':
  142.                         if(op[1] == '=')
  143.                                 return(OPERATOR_EQUAL);
  144.                 case '!':
  145.                         if(op[1] == '=')
  146.                                 return(OPERATOR_NOT_EQUAL);
  147.                 case '&':
  148.                         if(op[1] == '&')
  149.                                 return(OPERATOR_LOGICAL_AND);
  150.                         else
  151.                                 return(OPERATOR_BITWISE_AND);
  152.                 case '^':
  153.                         return(OPERATOR_BITWISE_XOR);
  154.                 case '|':
  155.                         if(op[1] == '|')
  156.                                 return(OPERATOR_LOGICAL_OR);
  157.                         else
  158.                                 return(OPERATOR_BITWISE_OR);
  159.         }
  160.         return(OPERATOR_ERROR);
  161. }
  162.  
  163.  
  164.  
  165.  
  166. int test_operator_at_precedence(int operator, int precedence)
  167. {
  168.         switch(precedence) {
  169.                 case 13:
  170.                         return((operator == OPERATOR_MUL) || (operator == OPERATOR_DIV)
  171.                                || (operator == OPERATOR_MOD));
  172.                 case 12:
  173.                         return((operator == OPERATOR_ADD) || (operator == OPERATOR_SUB));
  174.                 case 11:
  175.                         return((operator == OPERATOR_SHIFT_LEFT) || (operator == OPERATOR_SHIFT_RIGHT));
  176.                 case 10:
  177.                         return((operator == OPERATOR_LESS_THAN) || (operator == OPERATOR_LESS_OR_EQUAL)
  178.                                || (operator == OPERATOR_GREATER_THAN) || (operator == OPERATOR_GREATER_OR_EQUAL));
  179.                 case 9:
  180.                         return((operator == OPERATOR_EQUAL) || (operator == OPERATOR_NOT_EQUAL));
  181.                 case 8:
  182.                         return(operator == OPERATOR_BITWISE_AND);
  183.                 case 7:
  184.                         return(operator == OPERATOR_BITWISE_XOR);
  185.                 case 6:
  186.                         return(operator == OPERATOR_BITWISE_OR);
  187.                 case 5:
  188.                         return(operator == OPERATOR_LOGICAL_AND);
  189.                 default: /* Makes the compiler shut up */
  190.                 case 4:
  191.                         return(operator == OPERATOR_LOGICAL_OR);
  192.         }
  193. }
  194.  
  195.  
  196. int calc(struct prog_info *pi, int left, int operator, int right) // TODO: Sjekk litt resultater
  197. {
  198.         switch(operator) {
  199.                 case OPERATOR_MUL:
  200.                         return(left * right);
  201.                 case OPERATOR_DIV:
  202.                         if(right == 0) {
  203.                                 print_msg(pi, MSGTYPE_ERROR, "Division by zero");
  204.                                 return(0);
  205.                         }
  206.                         return(left / right);
  207.                 case OPERATOR_MOD:
  208.                         if(right == 0) {
  209.                                 print_msg(pi, MSGTYPE_ERROR, "Division by zero (modulus operator)");
  210.                                 return(0);
  211.                         }
  212.                     return(left % right);
  213.                 case OPERATOR_ADD:
  214.                         return(left + right);
  215.                 case OPERATOR_SUB:
  216.                         return(left - right);
  217.                 case OPERATOR_SHIFT_LEFT:
  218.                         return(left << right);
  219.                 case OPERATOR_SHIFT_RIGHT:
  220.                         return((unsigned)left >> right);
  221.                 case OPERATOR_LESS_THAN:
  222.                         return(left < right);
  223.                 case OPERATOR_LESS_OR_EQUAL:
  224.                         return(left <= right);
  225.                 case OPERATOR_GREATER_THAN:
  226.                         return(left > right);
  227.                 case OPERATOR_GREATER_OR_EQUAL:
  228.                         return(left >= right);
  229.                 case OPERATOR_EQUAL:
  230.                         return(left == right);
  231.                 case OPERATOR_NOT_EQUAL:
  232.                         return(left != right);
  233.                 case OPERATOR_BITWISE_AND:
  234.                         return(left & right);
  235.                 case OPERATOR_BITWISE_XOR:
  236.                         return(left ^ right);
  237.                 case OPERATOR_BITWISE_OR:
  238.                         return(left | right);
  239.                 case OPERATOR_LOGICAL_AND:
  240.                         return(left && right);
  241.                 default: /* Make the compiler shut up */
  242.                 case OPERATOR_LOGICAL_OR:
  243.                         return(left || right);
  244.         }
  245. }
  246.  
  247. /* If found, return the ID of the internal function */
  248. int get_function(char *function)
  249. {
  250.         int i;
  251.  
  252.         for(i = 0; i < FUNCTION_COUNT; i++) {
  253.                 if(!nocase_strncmp(function, function_list[i], strlen(function_list[i])))
  254.         {
  255.             /*
  256.             ** some more checks to allow whitespace between function name
  257.             ** and opening brace...
  258.             */
  259.             char *tmp = function + strlen(function_list[i]);
  260.             while (*tmp <= ' ')
  261.                 tmp++;
  262.             if (*tmp != '(')
  263.                 continue;
  264.  
  265.       return(i);
  266.   }  
  267.     }  
  268.         return(-1);
  269. }
  270.  
  271. unsigned int do_function(int function, int value)
  272. {
  273.         switch(function) {
  274.                 case FUNCTION_LOW:
  275.                 case FUNCTION_BYTE1:
  276.                         return(value & 0xFF);
  277.                 case FUNCTION_HIGH:
  278.                 case FUNCTION_BYTE2:
  279.                         return((value >> 8) & 0xff);
  280.                 case FUNCTION_BYTE3:
  281.                         return((value >> 16) & 0xff);
  282.                 case FUNCTION_BYTE4:
  283.                         return((value >> 24) & 0xff);
  284.                 case FUNCTION_LWRD:
  285.                         return(value & 0xffff);
  286.                 case FUNCTION_HWRD:
  287.                         return((value >> 16) & 0xffff);
  288.                 case FUNCTION_PAGE:
  289.                         return((value >> 16) & 0xff);
  290.                 case FUNCTION_EXP2:
  291.                         return(1 << value);
  292.                 case FUNCTION_LOG2:
  293.                         return(log_2(value));
  294.                 default:
  295.                         return(0);
  296.         }
  297. }
  298.  
  299.  
  300. int get_symbol(struct prog_info *pi, char *label_name, int *data)
  301. {
  302.         struct label *label;
  303.         struct macro_call *macro_call;
  304.  
  305.         if(get_constant(pi,label_name,data)) return(True);
  306.         if(get_variable(pi,label_name,data)) return(True);
  307.  
  308.         for(macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack) {
  309.                 for(label = pi->macro_call->first_label; label; label = label->next)
  310.                         if(!nocase_strcmp(label->name, label_name)) {
  311.                                 if(data)
  312.                                         *data = label->value;
  313.                                 return(True);
  314.                         }
  315.         }
  316.  
  317.         if(get_label(pi,label_name,data)) return(True);
  318.         return(False);
  319. }
  320.  
  321.  
  322. int par_length(char *data)
  323. {
  324.         int i = 0, b_count = 1;
  325.  
  326.         for(;;) {
  327.                 if(data[i] == ')') {
  328.                         b_count--;
  329.                         if(!b_count)
  330.                                 return(i);
  331.                 }
  332.                 else if(data[i] == '(')
  333.                         b_count++;
  334.                 else if(data[i] == '\0')
  335.                         return(-1);
  336.                 i++;
  337.         }
  338. }
  339.  
  340. int get_expr(struct prog_info *pi, char *data, int *value) {
  341.   /* Definition */
  342.         int ok, end, i, count, first_flag, length, function;
  343.         char unary, *label;
  344.         struct element *element, *first_element = NULL, *temp_element;
  345.         struct element **last_element = &first_element;
  346.  
  347.   /* Initialisation */
  348.   first_flag  = True;
  349.   ok          = True;
  350.   end         = False;
  351.   count       = 0;
  352.   unary       = 0;
  353.   /* the expression parser loop */
  354.         for(i = 0; ; i++) {
  355.           /* horizontal space is just skipped */
  356.                 if(IS_HOR_SPACE(data[i]));
  357.                 /* test for clean or premature end */
  358.                 else if(IS_END_OR_COMMENT(data[i])) {
  359.                         if((count % 2) != 1)
  360.                                 print_msg(pi, MSGTYPE_ERROR, "Missing value in expression");
  361.                         else
  362.                                 end = True;
  363.                         break;
  364.                 }
  365.                 else if(first_flag && IS_UNARY(data[i])) {
  366.                         unary = data[i];
  367.                         first_flag = False;
  368.                 }
  369.                 else if((count % 2) == 1) {
  370.                         if(!IS_OPERATOR(data[i])) {
  371.                                 print_msg(pi, MSGTYPE_ERROR, "Illegal operator '%c'", data[i]);
  372.                                 break;
  373.                         }
  374.                         element = malloc(sizeof(struct element));
  375.                         if(!element) {
  376.                                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  377.                                 ok = False;
  378.                                 break;
  379.                         }
  380.                         element->next = NULL;
  381.                         element->data = get_operator(&data[i]);
  382.                         if(element->data == OPERATOR_ERROR) {
  383.                                 if(IS_2ND_OPERATOR(data[i + 1]))
  384.                                         print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c%c", data[i], data[i + 1]);
  385.                                 else
  386.                                         print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c", data[i]);
  387.                                 break;
  388.                         }
  389.                         *last_element = element;
  390.                         last_element = &element->next;
  391.                         if(IS_2ND_OPERATOR(data[i + 1]))
  392.                                 i++;
  393.                         count++;
  394.                         first_flag = True;
  395.                         unary = 0;
  396.                 }
  397.                 else {
  398.                         element = malloc(sizeof(struct element));
  399.                         if(!element) {
  400.                                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  401.                                 ok = False;
  402.                                 break;
  403.                         }
  404.                         element->next = NULL;
  405.                         length = 0;
  406.                         if(isdigit(data[i])) {
  407.                                 if(tolower(data[i + 1]) == 'x') {
  408.                                         i += 2;
  409.                                         while(isxdigit(data[i + length])) length++; // TODO: Sjekk overflow
  410.                                         element->data = atox_n(&data[i], length);
  411.                                 }
  412.                                 else if(tolower(data[i + 1]) == 'b') {
  413.                                         i += 2;
  414.                                         element->data = 0;
  415.                                         while((data[i + length] == '1') || (data[i + length] == '0')) {
  416.                                                 element->data <<= 1;
  417.                                                 element->data |= data[i + length++] - '0'; // TODO: Sjekk overflow
  418.                                         }
  419.                                 }
  420.                                 else {
  421.                                         while(isdigit(data[i + length])) length++;
  422.                                           element->data = atoi_n(&data[i], length); // TODO: Sjekk overflow
  423.                                 }
  424.                         }
  425.                         else if(data[i] == '$') {
  426.                                 i++;
  427.                                 while(isxdigit(data[i + length])) length++;
  428.                                 element->data = atox_n(&data[i], length); // TODO: Sjekk overflow
  429.                         }
  430.                         else if(data[i] == '\'') {
  431.                                 i++;
  432.                                 if(data[i+1] != '\'') {
  433.                                         print_msg(pi, MSGTYPE_ERROR, "Not a correct character ! Use 'A' !");
  434.                                         break;
  435.                                 }
  436.                                 element->data = data[i];
  437.                                 length = 2;
  438.                         }
  439.                         else if(data[i] == '(') {
  440.                                 i++;
  441.                                 length = par_length(&data[i]);
  442.                                 if(length == -1) {
  443.                                         print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  444.                                         break;
  445.                                 }
  446.                                 data[i + length++] = '\0';
  447.                                 ok = get_expr(pi, &data[i], &element->data);
  448.                                 if(!ok)
  449.                                         break;
  450.                         }
  451.                         /* test for internal function */
  452.                         else if((function = get_function(&data[i])) != -1) {
  453.                                 while(data[i] != '(')
  454.                                         i++;
  455.                                 i++;
  456.                                 length = par_length(&data[i]);
  457.                                 if(length == -1) {
  458.                                         print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  459.                                         break;
  460.                                 }
  461.                                 data[i + length++] = '\0';
  462.                                 ok = get_expr(pi, &data[i], &element->data);
  463.                                 if(!ok)
  464.                                         break;
  465.                                 element->data = do_function(function, element->data);
  466.                         }
  467.                         else if(!nocase_strncmp(&data[i], "defined(", 8)) {
  468.                                 i += 8;
  469.                                 length = par_length(&data[i]);
  470.                                 if(length == -1) {
  471.                                         print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  472.                                         break;
  473.                                 }
  474.                                 data[i + length++] = '\0';
  475.                                 if(get_symbol(pi, &data[i], NULL))
  476.                                         element->data = 1;
  477.                                 else
  478.                                         element->data = 0;
  479.                         }
  480.                         else if(!nocase_strncmp(&data[i], "supported(", 10)) {
  481.                                 i += 10;
  482.                                 length = par_length(&data[i]);
  483.                                 if(length == -1) {
  484.                                         print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
  485.                                         break;
  486.                                 }
  487.                                 data[i + length++] = '\0';
  488.                                 element->data=is_supported(pi, &data[i]);
  489.                                 if (element->data<0) {
  490.                                         if (toupper(data[i])=='X') {
  491.                                                 if (pi->device->flag&DF_NO_XREG) element->data = 0;
  492.                                                 else element->data = 1;
  493.                                         }
  494.                                         else if (toupper(data[i])=='Y') {
  495.                                                 if (pi->device->flag&DF_NO_YREG) element->data = 0;
  496.                                                 else element->data = 1;
  497.                                         }
  498.                                         else if (toupper(data[i])=='Z')
  499.                                                 element->data = 1;
  500.                                         else {
  501.                                                 print_msg(pi, MSGTYPE_ERROR, "Unknown mnemonic: %s",&data[i]);
  502.                                                 element->data = 0;
  503.                                         }
  504.                                 }
  505.                         }
  506.                         else {
  507.                                 while(IS_LABEL(data[i + length])) length++;
  508.                                 if((length == 2) && !nocase_strncmp(&data[i], "PC", 2))
  509.                                         element->data = pi->cseg_addr;
  510.                                 else {
  511.                                         label = malloc(length + 1);
  512.                                         if(!label) {
  513.                                                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  514.                                                 ok = False;
  515.                                                 break;
  516.                                         }
  517.                                         strncpy(label, &data[i], length);
  518.                                         label[length] = '\0';
  519.                                         if(get_symbol(pi, label, &element->data))
  520.                                                 free(label);
  521.                                         else {
  522.                                                 print_msg(pi, MSGTYPE_ERROR, "Found no label/variable/constant named %s", label);
  523.                                                 free(label);
  524.                                                 break;
  525.                                         }
  526.                                 }
  527.                         }
  528.                         /* now the expression has been evaluated */
  529.                         i += length - 1;
  530.                         switch(unary) { // TODO: Få den til å takle flere unary på rad.
  531.                                 case '-':
  532.                                         element->data = -element->data;
  533.                                         break;
  534.                                 case '!':
  535.                                         element->data = !element->data;
  536.                                         break;
  537.                                 case '~':
  538.                                         element->data = ~element->data;
  539.                         }
  540.                         *last_element = element;
  541.                         last_element = &element->next;
  542.                         count++;
  543.                         first_flag = False;
  544.                 }
  545.         }
  546.         if(end) {
  547.                 for(i = 13; (i >= 4) && (count != 1); i--) {
  548.                         for(element = first_element; element->next;) {
  549.                                 if(test_operator_at_precedence(element->next->data, i)) { // TODO: Vurder en hi_i for kjapphet
  550.                                         element->data = calc(pi, element->data, element->next->data, element->next->next->data);
  551.                                         temp_element = element->next->next->next;
  552.                                         free(element->next->next);
  553.                                         free(element->next);
  554.                                         count -= 2;
  555.                                         element->next = temp_element;
  556.                                 }
  557.                                 else
  558.                                         element = element->next->next;
  559.                         }
  560.                 }
  561.                 *value = first_element->data;
  562.         }
  563.         for(element = first_element; element;) {
  564.                 temp_element = element;
  565.                 element = element->next;
  566.                 free(temp_element);
  567.         }
  568.         return(ok);
  569. }
  570.  
  571.  
  572. /* end of expr.c */
  573.  
  574.