Exemplo n.º 1
0
static inline PrintfError printf(PrintfPacket* queue, All... all) [[hc,cpu]] {
  unsigned int count = 0;
  countArg(count, all...);

  PrintfError error = PRINTF_SUCCESS;

  if (count + 1 + queue[1].data.ui > queue[0].data.ui) {
    error = PRINTF_BUFFER_OVERFLOW;
  } else {

#if 0
    /*** FIXME: hcc didn't promote the address of the atomic type into global address space ***/
    unsigned int offset = queue[1].data.ai.fetch_add(count + 1);
#endif
    unsigned int offset = __hsail_atomic_fetch_add_unsigned(&(queue[1].data.ui),count + 1);
    if (offset + count + 1 < queue[0].data.ui) {
      set_batch(queue, offset, count, all...);
    }
    else {
      error = PRINTF_BUFFER_OVERFLOW;
    }
  }

  return error;
}
Exemplo n.º 2
0
static inline void countArg(unsigned int& count, const T& t, const Rest&... rest) [[hc,cpu]] {
  ++count;
  countArg(count,rest...);
}
Exemplo n.º 3
0
int semantic_check(node *ast) {

    if(!ast)
        return 0;

    int btype;

    switch((int)ast->kind) {
        case UNKNOWN:
            break;

        case NSCOPE:
            lhs = semantic_check(ast->scope.declarations);
            if(lhs == -1)
                return -1;

            rhs = semantic_check(ast->scope.statements);
            if(rhs == -1)
                return -1;

            if(lhs > rhs)
                return lhs;
            else
                return rhs;
            break;

        case NDECLARATIONS:
            lhs = semantic_check(ast->declarations.declarations);
            if(lhs == -1)
                return -1;

            rhs = semantic_check(ast->declarations.declaration);
            if(rhs == -1)
                return -1;
            else
                return rhs;
            break;

        case NSTATEMENTS:
            lhs = semantic_check(ast->statements.statements);
            if(lhs == -1)
                return -1;

            rhs = semantic_check(ast->statements.statement);
            if(rhs == -1)
                return -1;
            else
                return rhs;
            break;

        case NTYPE_DECLARATION:
            if(isVarDeclared(sym_table, ast->type_declaration.id, scopeNum)) {
                fprintf(errorFile, "Error: Variable cannot be re-declared within the same scope\n");
                errorOccurred = 1;    
                return -1;
            }
            else
                return semantic_check(ast->type_declaration.type);
            break;

        case NASSIGN_DECLARATION:
            lhs = semantic_check(ast->assign_declaration.type);
            if(lhs == -1)
                return -1;

            rhs = semantic_check(ast->assign_declaration.expression);
            if(rhs == -1)
                return -1;

            if(isVarDeclared(sym_table, ast->assign_declaration.id, scopeNum)) {
                fprintf(errorFile, "Error: Variable cannot be re-declared within the same scope\n");
                errorOccurred = 1;
                return -1;                                                            
            }

            if(lhs == rhs)
                return lhs;

            else if((lhs == IVEC2 || lhs == IVEC3 || lhs == IVEC4) && (rhs == INT))
                return INT;

            else if((lhs == BVEC2 || lhs == BVEC3 || lhs == BVEC4) && (rhs == BOOL))
                return BOOL;

            else if((lhs == VEC2 || lhs == VEC3 || lhs == VEC4) && (rhs == FLOAT))
                return FLOAT;

            else {
                fprintf(errorFile, "Error: Declaration failed, type mismatch in assignment\n");
                errorOccurred = 1;
                return -1;
            }
            break;

        case NCONST_DECLARATION: 
            lhs = semantic_check(ast->const_declaration.type);
            if(lhs == -1)
                return -1;

            rhs = semantic_check(ast->const_declaration.expression);
            if(rhs == -1)
                return -1;

            type_class = get_tClass(sym_table, ast->const_declaration.type->id_variable.id);
            if(ast->const_declaration.type->kind != NINT_EXPR && ast->const_declaration.type->kind != NFLOAT_EXPR && ast->const_declaration.type->kind != NBOOL_EXPR && ast->const_declaration.type->kind != NTYPE_EXPR && ast->const_declaration.type->kind != NARRAY_VARIABLE && type_class != _CONST && type_class != UNIFORM) {
                fprintf(errorFile, "Error: 'const' qualified variables must be initialized with a literal value or with a uniform variable\n");
                errorOccurred = 1;
                return -1;
            }

            if(lhs == rhs)
                return lhs;

            else if((lhs == IVEC2 || lhs == IVEC3 || lhs == IVEC4) && (rhs == INT))
                return INT;

            else if((lhs == VEC2 || lhs == VEC3 || lhs == VEC4) && (rhs == FLOAT))
                return FLOAT;

            else if((lhs == BVEC2 || lhs == BVEC3 || lhs == BVEC4) && (rhs == BOOL))
                return BOOL;

            else {
                fprintf(errorFile, "Error: Type mismatch in assignment\n");
                errorOccurred = 1;
                return -1;
            }
            break;

        case NASSIGN_STATEMENT:
            lhs = semantic_check(ast->assign_statement.variable);
            if(lhs == -1)
                return -1;

            rhs = semantic_check(ast->assign_statement.expression);
            if(rhs == -1)
                return -1;
            else
                return CheckTypes(rhs, lhs);

            break;

        case NIF_STATEMENT:
            lhs = semantic_check(ast->if_statement.condition);

            if(lhs == -1)
                return -1;

            if(lhs == BOOL) 
                semantic_check(ast->if_statement.statement);

            else {
                fprintf(errorFile, "Error: Condition must be of type 'bool'\n");
                errorOccurred = 1;
                return -1;
            }                                     
            break;

        case NIF_ELSE_STATEMENT:
            lhs = semantic_check(ast->if_else_statement.condition);
            if(lhs == -1)
                return -1;

            if(lhs == BOOL) {
                semantic_check(ast->if_else_statement.statement);
                semantic_check(ast->if_else_statement.else_statement);
            }
            else {
                fprintf(errorFile, "Error: Condition must be of type 'bool'\n");
                errorOccurred = 1;                                                        
                return -1;
            }
            break;

        case NSCOPE_STATEMENT:
            scopeNum++;
            check_prog_scope = semantic_check(ast->prog_scope.scope);
            scopeNum--;
            return check_prog_scope;
            break;

        //unary expression
        case NUNARY_EXPR:
            rhs = semantic_check(ast->unary_expr.right);
            if(rhs == -1)
                return -1;

            if(ast->unary_expr.op == MINUS_OPS) {

                if(rhs == BOOL || rhs == BVEC2|| rhs == BVEC3|| rhs == BVEC4){
                    fprintf(errorFile, "Error: All operands to arithmetic operators must have arithmetic types\n");
                    errorOccurred = 1;                                                                                                
                    return -1;
                }
                else
                    return rhs;
            }
            if(ast->unary_expr.op == NOT_OPS) {

                if(rhs != BOOL || rhs != BVEC2 || rhs != BVEC3 || rhs != BVEC4) {
                    fprintf(errorFile, "Error: All operands to logical operators must have boolean types\n");
                    errorOccurred = 1;
                    return -1;
                }
                else
                    return rhs;
            }
            break;

        case NBINARY_EXPR:
            rhs = semantic_check(ast->binary_expr.right);
            if(rhs == -1)
                return -1;
                
            lhs = semantic_check(ast->binary_expr.left);
            btype = CheckTypes(rhs, lhs);
            
            if(lhs == -1){
                return -1;
            }else if(btype == -1){
                fprintf(errorFile, "Error: The operands to binary operators must have same base types\n");
                errorOccurred = 1;
                return -1;
            }else if(vectorChecking(rhs) == 1 && vectorChecking(lhs) == 1){
                if(vectorCompare(rhs, lhs) == 0){
                    fprintf(errorFile, "Error: The vector operands to binary operators must have same order\n");
                    errorOccurred = 1;
                    return -1;
                }else{
                    btype = BOOL;
                    ast->binary_expr.type = btype;
                    return btype;
                }
            }else if(ast->binary_expr.op == AND_OPS || ast->binary_expr.op == OR_OPS ||ast->binary_expr.op == EQ_OPS || ast->binary_expr.op == NEQ_OPS){
                if(rhs != BOOL || rhs != BVEC2 || rhs != BVEC3 || rhs != BVEC4 || lhs != BOOL || lhs != BVEC2 || lhs != BVEC3 || lhs != BVEC4){
                    fprintf(errorFile, "Error: All operands to logical operators must have boolean types\n");
                    errorOccurred = 1;
                    return -1;
                }else if((vectorChecking(rhs) && !vectorChecking(lhs)) || (!vectorChecking(rhs) && vectorChecking(lhs))){
                    fprintf(errorFile, "Error: The operands to logical operators must be both vectors or both scalars\n");
                    errorOccurred = 1;
                    return -1;
                }else{
                    btype = BOOL;
                    ast->binary_expr.type = btype;
                    return btype;
                }
            }else if(ast->binary_expr.op == LESS_OPS || ast->binary_expr.op == LEQ_OPS ||ast->binary_expr.op == GTR_OPS || ast->binary_expr.op == GEQ_OPS || ast->binary_expr.op == PLUS_OPS || ast->binary_expr.op == MINUS_OPS  || ast->binary_expr.op == DIVIDE_OPS || ast->binary_expr.op == POW_OPS || ast->binary_expr.op == TIMES_OPS){
                if(rhs == BOOL || rhs == BVEC2|| rhs == BVEC3|| rhs == BVEC4 || lhs == BOOL || lhs == BVEC2|| lhs == BVEC3|| lhs == BVEC4){
                    fprintf(errorFile, "Error: All operands to arithmetic operators must have arithmetic types.\n");
                    errorOccurred = 1;                                                                                                
                    return -1;
                }else if( ast->binary_expr.op != TIMES_OPS && (vectorChecking(rhs) == 1 || vectorChecking(lhs) == 1)){
                    fprintf(errorFile, "Error: The operands to arithmetic operators (except for times) must be both vectors or both scalars\n");
                    errorOccurred = 1;
                    return -1;
                }else{
                    btype = BOOL;
                    ast->binary_expr.type = btype;
                    return btype;
                }
            }
            else
                return -1;

            break;

        case NBRACKETS_EXPR:
            return semantic_check(ast->brackets_expr.expression);
            break;

        case NFUNC_EXPR:
            rhs = semantic_check(ast->func_expr.arguments_opt);

            if(rhs == -1)
                return -1;

            switch(ast->func_expr.func) {

                case 0:
                    if(rhs == IVEC3 || rhs == IVEC4)
                        return INT;
                    else if(rhs == VEC3 || rhs == VEC4)
                        return FLOAT;
                    else {
                        fprintf(errorFile, "Error: Function argument doesn't match as expected ('db3' supports arguments of type 'vec3', 'vec4', 'ivec3' & 'ivec4')\n");
                        errorOccurred = 1;
                        return -1;
                    }
                    break;

                case 1:
                    if(rhs == VEC4)
                        return VEC4;
                    else {
                        fprintf(errorFile, "Error: Function argument doesn't match as expected ('lit' only supports argument of type 'vec4')\n");
                        errorOccurred = 1;
                        return -1;
                    }
                    break;

                case 2:
                    if(rhs == FLOAT || rhs == INT)
                        return FLOAT;
                    else {
                        fprintf(errorFile, "Error: Function argument doesn't match as expected ('rsq' supports arguments of type 'int' & 'float')\n");
                        errorOccurred = 1;
                        return -1;
                    }
                    break;

                default:
                    fprintf(errorFile, "Error: Function name doesn't match as expected (supported function names - 'db3', 'lit' & 'rsq')\n");
                    errorOccurred = 1;
                    return -1;
                    break;
            }
            break;

        case NTYPE_EXPR:
            lhs = semantic_check(ast->type_expr.type);
            if(lhs == -1)
                return -1;
                
            rhs = semantic_check(ast->type_expr.arguments_opt);
            if(rhs == -1)
                return -1;

            numArgs = countArg(ast->type_expr.arguments_opt);

            if((lhs == IVEC2 && numArgs == 2) || (lhs == IVEC3 && numArgs == 3) || (lhs == IVEC4 && numArgs == 4) || (lhs == BVEC2 && numArgs == 2) || (lhs == BVEC3 && numArgs == 3) || (lhs == BVEC4 && numArgs == 4) || (lhs == VEC2 && numArgs == 2) || (lhs == VEC3 && numArgs == 3) || (lhs == VEC4 && numArgs == 4) || (lhs == BOOL && numArgs == 1) || (lhs == INT && numArgs == 1) || (lhs == FLOAT && numArgs == 1))
                ;
            else {
                fprintf(errorFile, "Error: Costructors for basic types (bool, int, float) must have one argument and vector types must have as many arguments as there are elements in the vector\n");
                errorOccurred = 1;
                return -1;
            }

            if(lhs == rhs)
                return lhs;

            else if((lhs == IVEC2 || lhs == IVEC3 || lhs == IVEC4) && (rhs == INT))
                return INT;

            else if((lhs == VEC2 || lhs == VEC3 || lhs == VEC4) && (rhs == FLOAT))
                return FLOAT;

            else if((lhs == BVEC2 || lhs == BVEC3 || lhs == BVEC4) && (rhs == BOOL))
                return BOOL;
            
            else {
                fprintf(errorFile, "Error: Type mismatch found\n");
                errorOccurred = 1;
                return -1;
            }
            break;

        case NVAR_EXPR:
            return semantic_check(ast->var_expr.variable);            
            break;

        case NINT_EXPR:
            return INT;
            break;

        case NFLOAT_EXPR:
            return FLOAT;
            break;

        case NBOOL_EXPR:
            return BOOL;
            break;

        case NID_VARIABLE:
            id = ast->id_variable.id;
            if(!isVarDeclaredInScope(sym_table, id, scopeNum)) {
                fprintf(errorFile, "Error: Variable cannot be used before it is declared\n");
                errorOccurred = 1;
                return -1;
            }
            else if(strcmp(id, "TEMP") == 0 || strcmp(id, "ADDRESS") == 0) {
                fprintf(errorFile, "Error: Reserved words can not be used as variable\n");
                errorOccurred = 1;
                return -1;
            }
            else {
                type_class = get_tClass(sym_table, id); 
                if(type_class == _CONST) {
                    fprintf(errorFile, "Error: Variable cannot be used before it is declared\n");
                    errorOccurred = 1;
                    return -1;
                }
                return get_data_type(sym_table, id);
            }
            break;

        case NARRAY_VARIABLE:
            x = ast->array_variable.index;
            type = get_data_type(sym_table, ast->array_variable.id);

            if(type == IVEC2 || type == IVEC3 || type == IVEC4 || type == BVEC2 || type == BVEC3 || type == BVEC4 || type == VEC2 || type == VEC3 || type == VEC4)
                ;
            else {
                fprintf(errorFile, "Error: Only 'vec' type supported\n");
                errorOccurred = 1;
                return -1;
            }
            if((type == IVEC2 && x < 2) || (type == IVEC3 && x < 3) || (type == IVEC4 && x < 4) || (type == BVEC2 && x < 2) || (type == BVEC3 && x < 3) || (type == BVEC4 && x < 4) || (type == VEC2 && x < 2) || (type == VEC3 && x < 3) || (type == VEC4 && x < 4))
                ;
            else {
                fprintf(errorFile, "Error: Index limit exceeded\n");
                errorOccurred = 1;
                return -1;
            }

            if(type == IVEC2 || type == IVEC3 || type == IVEC4)
                return INT;
            
            if(type == BVEC2 || type == BVEC3 || type == BVEC4)
                return BOOL;

            if(type == VEC2 || type == VEC3 || type == VEC4)
                return FLOAT;

            break;

        case NARGS_ARGUMENTS:
            lhs = semantic_check(ast->args_arguments.arguments);
            if(lhs == -1)
                return -1;
                
            rhs = semantic_check(ast->args_arguments.expression);
            if(rhs == -1)
                return -1;

            else if(lhs == rhs)
                return lhs;

            else {
                fprintf(errorFile, "Error: Mismatch in arguments\n");
                errorOccurred = 1;
                return -1;
            }
            break;

        case NEXPR_ARGUMENTS:
            return semantic_check(ast->expr_arguments.expression);
            break;

        case NARGUMENTS_OPT:
            return semantic_check(ast->arguments_opt.arguments);
            break;

        case NTYPE:
            return ast->type.type_kind;
            break;

        case NPROG_SCOPE:
            scopeNum++;
            check_prog_scope = semantic_check(ast->prog_scope.scope);
            scopeNum--;
            return check_prog_scope;
            break;

        default:
            return -1;
            break;
    }
    return 0; // failed checks
}
Exemplo n.º 4
0
int main(int argc, char *argv[]) {

  /* Declare variables */
  char buffer [1024];
  int argCount, outFile, status, special;
  pid_t pid;

  // Loop forever, exit case below
  while (1) {
    printf("mysh> ");
    // Get user input
    fgets(buffer, 1024, stdin);
    // Count number of arguments in input (number of spaces)
    argCount = countArg(buffer);
    // Make an array, 1 item larger than the number of args - holds NULL for execvp
    char * args[argCount + 1];
    //printf("hasChar('>'): %d\n", hasChar(buffer, '>'));
    special = parseCmd(buffer, args, argCount);


    // Only continue if not a blank input
    if (strcmp(buffer, "\n") != 0) {
      // Exit if necessary
      if (strcmp(args[0], "exit") == 0) {
        if (argCount != 1) {
          fprintf(stderr, "Error!\n");
        } else {
          exit(0);
        }
      // Print working directory
      } else if (strcmp(args[0], "pwd") == 0) {
        printf("%s\n", getcwd(buffer, 1024));
      // Change working directory, possibly moving to $HOME
      } else if (strcmp(args[0], "cd") == 0) {
        if (args[1] == NULL) {
          chdir(getenv("HOME"));
        } else {
          if (chdir(args[1]) == -1) {
            fprintf(stderr, "Error!\n");
          }
        }
      } else {

        // Fork the process
        pid = fork();

        //printf("This line is from pid %d\n", pid);
        if (pid == 0) {

          char * args1[special + 1];
          char * args2[argCount - special];
          int i;

          //printf("args1 size: %ld\n", sizeof(args1) / sizeof(args1[0]));
          //printf("args2 size: %ld\n", sizeof(args2) / sizeof(args2[0]));

          // Set up args for execvp (if piped)
          args1[special] = NULL;
          args2[argCount - special + 1] = NULL;

          //printf("special: %d\n", special);

          // If going to redirect output to a file
          if (special == -1 || special == -2) {
            printf("Using file: %s\n", args[argCount - 1]);

            // Create new file
            if (special == -1) {
              outFile = open(args[argCount - 1], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
            // Appending output file
            } else {
              outFile = open(args[argCount - 1], O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
            }

            if (outFile < 0) {
              fprintf(stderr, "Error: Cannot open output file: %s\n", args[argCount - 1]);
              exit(1);
            }
            // Change output stream from std out to file
            if (dup2(outFile, 1) == -1) {
              printf("error! - dup2\n");
            }
            args[argCount - 1] = NULL;
            args[argCount - 2] = NULL;

          // Piping output to another file
          } else if (special > 0) {
            // Set up a pipe for output

            if (special == argCount - 1) {
              fprintf(stderr, "Error!\n");
              exit(1);
            }

            for (i = 0; i < special; i++) {
              args1[i] = args[i];
            }

            for (i = 0; i < argCount - special; i++) {
              args2[i] = args[i + special + 1];
            }

/*
            for (i = 0; i < sizeof(args1)/sizeof(args1[0]); i++) {
              printf("args1[%d]: %s\n", i, args1[i]);
            }
            for (i = 0; i < sizeof(args2)/sizeof(args2[0]); i++) {
              printf("args2[%d]: %s\n", i, args2[i]);
            }
*/

            // ls -la | grep Makefile
            // 0   1  2  3      4
            //
            // argCount = 5, special = 2
            // args1[2], args2[2]
            // 3 = [special + 1], 3 = [argCount - special]

          }

          // Run normal execvp if not piping
          if (special < 1) {
            if (execvp(args[0], args) == -1) {
              fprintf(stderr, "Error!\n");
            }
          // If piping, fork process again and then execvp both commands
          } else {
            int pipeFd[2];
            int pipeId;

            // Pipe output and fork into 2 processes
            pipe(pipeFd);
            pipeId = fork();
            // Run 1st command (giving output)
            if (pipeId > 0) {
              // Close unused input pipe
              close(pipeFd[0]);
              // Close stdout, and replace with the pipe
              dup2(pipeFd[1], 1);
              // Run 1st command
              if (execvp(args1[0], args1) == -1) {
                fprintf(stderr, "Error\n");
                exit(1);
              }
              // Close now non-used output pipe pointer
              close(pipeFd[1]);
              exit(0);
            // Run 2nd command (recieving input)
            } else {
              // Close unused output pipe
              close(pipeFd[1]);
              // Close stdin, and replace with the pipe
              dup2(pipeFd[0], 0);
              // Run 2st command
              if (execvp(args2[0], args2) == -1) {
                fprintf(stderr, "Error\n");
                exit(1);
              }
              // Close now non-used input pipe pointer
              close(pipeFd[0]);
              exit(0);
            }
          }
          exit(1);
        // Parent process will wait for child process to exit
        } else { // Parent process
          wait(&status);
        }
      }
    }

  }
  close(outFile);
  exit(0);
}
Exemplo n.º 5
0
int countArg(node *arg)
{
    int count = 0;

    switch(arg->kind) {
        case NTYPE_EXPR:
            return ++count;
            break;

        case NFUNC_EXPR:
            return ++count;
            break;

        case NBRACKETS_EXPR:
            return ++count;
            break;

        case NBINARY_EXPR:
            return ++count;
            break;

        case NUNARY_EXPR:
            return ++count;
            break;

        case NINT_EXPR:
            return ++count;
            break;

        case NFLOAT_EXPR:
            return ++count;
            break;

        case NBOOL_EXPR:
            return ++count;
            break;

        case NARRAY_VARIABLE:
            return ++count;
            break;

        case NVAR_EXPR:
            return ++count;
            break;

        case NID_VARIABLE:
            return ++count;
            break;

        case NARGS_ARGUMENTS:
            ++count;
            count += countArg(ast->args_arguments.arguments);
            return count;
            break;

        case NEXPR_ARGUMENTS:
            return countArg(ast->expr_arguments.expression);
            break;

        default:
            return -1;
            break;
    }
    return count;
}