浏览代码

Implemented permutate patch

Andrea Gussoni 8 年之前
父节点
当前提交
2b63865fdf
共有 3 个文件被更改,包括 76 次插入0 次删除
  1. 3 0
      acse/Acse.lex
  2. 56 0
      acse/Acse.y
  3. 17 0
      tests/permutate/permutate.src

+ 3 - 0
acse/Acse.lex

@@ -88,6 +88,9 @@ ID       [a-zA-Z_][a-zA-Z0-9_]*
 "&&"              { return ANDAND; }
 "||"              { return OROR; }
 ","               { return COMMA; }
+"permutate"       { return PERMUTATE; }
+"q["              { return LXSQ; }
+"]p"              { return RXSQ; }
 
 "do"              { return DO; }
 "else"            { return ELSE; }

+ 56 - 0
acse/Acse.y

@@ -16,6 +16,7 @@
 
 #include <stdio.h>       
 #include <stdlib.h>
+#include <stdint.h>
 #include <assert.h>
 #include "axe_struct.h"
 #include "axe_engine.h"
@@ -121,6 +122,7 @@ t_io_infos *file_infos;    /* input and output files used by the compiler */
 %token RETURN
 %token READ
 %token WRITE
+%token PERMUTATE LXSQ RXSQ
 
 %token <label> DO
 %token <while_stmt> WHILE
@@ -134,6 +136,7 @@ t_io_infos *file_infos;    /* input and output files used by the compiler */
 %type <decl> declaration
 %type <list> declaration_list
 %type <label> if_stmt
+%type <list> cst_list
 
 /*=========================================================================
                           OPERATOR PRECEDENCES
@@ -249,9 +252,62 @@ statement   : assign_statement SEMI      { /* does nothing */ }
 control_statement : if_statement         { /* does nothing */ }
             | while_statement            { /* does nothing */ }
             | do_while_statement SEMI    { /* does nothing */ }
+            | permutate_statement SEMI   { /* does nothung */ }
             | return_statement SEMI      { /* does nothing */ }
 ;
 
+cst_list : NUMBER { $$ = addFirst(NULL, (void *)(intptr_t)$1); }
+         | NUMBER COMMA cst_list { $$ = addFirst($3, (void*)(intptr_t)$1); }
+;
+
+permutate_statement : PERMUTATE LPAR IDENTIFIER COMMA LXSQ cst_list RXSQ RPAR
+                    {
+                        t_axe_variable *arr = getVariable(program, $3);
+                        if (!arr || !arr->isArray) {
+                            fprintf(stderr, "Permutate works only on array!");
+                            exit(-1);
+                        }
+
+                        t_list *cst_list = $6;
+                        int len = getLength(cst_list);
+                        t_list *regs = NULL;
+                        
+                        for (t_list *cur = cst_list; cur != 0; cur =LNEXT(cur)){
+                            int cst_idx = (int)(intptr_t)LDATA(cur);
+                            if (cst_idx >= arr->arraySize) {
+                                fprintf(stderr, "Illegal permutation index");
+                                exit(-1);
+                            }
+
+                            t_axe_expression idx = create_expression(cst_idx,
+                                IMMEDIATE);
+                            int tmp = loadArrayElement(program, $3, idx);
+                            regs = addLast(regs, (void *)(intptr_t)(tmp));
+                        }
+                        
+                        cst_list = removeFirst(addLast(cst_list, 
+                                                       LDATA(cst_list)));
+    
+                        for (t_list *cur = cst_list, *cur_reg = regs;
+                             cur != 0; cur = LNEXT(cur), 
+                             cur_reg = LNEXT(cur_reg)) {
+                            int cst_idx = (int)(intptr_t)LDATA(cur);
+                            int reg = (int)(intptr_t)LDATA(cur_reg);
+                            t_axe_expression idx = create_expression(cst_idx, 
+                                IMMEDIATE);
+                            t_axe_expression elem = create_expression(reg, 
+                                REGISTER);
+                            
+                            storeArrayElement(program, $3, idx, elem);
+                        }
+
+                        free(regs);
+                        free(cst_list);
+                        free $3;
+                    }
+;
+                            
+
 read_write_statement : read_statement  { /* does nothing */ }
                      | write_statement { /* does nothing */ }
 ;

+ 17 - 0
tests/permutate/permutate.src

@@ -0,0 +1,17 @@
+int arr[6];
+
+arr[0] = 10;
+arr[1] = 11;
+arr[2] = 12;
+arr[3] = 13;
+arr[4] = 14;
+arr[5] = 15;
+
+permutate(arr, q[ 4, 2, 0 ]p);
+
+write(arr[0]);
+write(arr[1]);
+write(arr[2]);
+write(arr[3]);
+write(arr[4]);
+write(arr[5]);