bool Codelet::matchesDep(lua_State *L, string dependency, vector<string> &reqdeps, vector<string> &outputs) { int codeletMatch = -1; string depBase = getVariableBasename(dependency); vector<string> depParams = getVariableParameters(dependency); for(int i=0; i<output.size(); i++) { string outBase = getVariableBasename(output[i]); vector<string> outParams = getVariableParameters(output[i]); if((depBase == outBase) && (depParams.size() == outParams.size())) { bool match = true; //Basenames match and parameter lists are same length, this codelet is a potential fit for(int j=0; j<outParams.size(); j++) { vector<string> ranges; //Check if output tag is in the codelet parameter list, if so, grab the parameter range if(params.find(outParams[j]) != params.end()) boost::split(ranges, params[outParams[j]], boost::is_any_of(",")); else ranges.push_back(outParams[j]); vector<vector<string> > prange; bool parammatch = false; //Determine if dependency parameter matches codelet parameter range for(int k=0; k<ranges.size(); k++) { vector<string> foo; boost::split(foo, ranges[k], boost::is_any_of(":")); if(foo.size() == 1) { if(depParams[j] == foo[0]) parammatch = true; } else { if((atoi(depParams[j].c_str()) >= atoi(foo[0].c_str())) && (atoi(depParams[j].c_str()) <= atoi(foo[1].c_str()))) parammatch = true; } } //This codelet does not match, we can move on to the next output if(!parammatch) { match = false; } } if(match) { codeletMatch = i; break; } } } if(codeletMatch > -1) { reqdeps.clear(); outputs.clear(); vector<pair<string,string> > kvset; string outBase = getVariableBasename(output[codeletMatch]); vector<string> outParams = getVariableParameters(output[codeletMatch]); for(int i=0; i<outParams.size(); i++) kvset.push_back(make_pair(outParams[i], depParams[i])); for(int i=0; i<deps.size(); i++) reqdeps.push_back(makeVariable(L, deps[i], kvset)); for(int i=0; i<output.size(); i++) outputs.push_back(makeVariable(L, output[i], kvset)); return true; } return false; }
inline CG<Base>& CG<Base>::operator-=(const CG<Base> &right) { if (isParameter() && right.isParameter()) { *value_ -= *right.value_; } else { CodeHandler<Base>* handler; if (isParameter()) { handler = right.getCodeHandler(); } else if (right.isParameter()) { if (right.isIdenticalZero()) { return *this; // nothing to do } handler = getCodeHandler(); } else { CPPADCG_ASSERT_UNKNOWN(getCodeHandler() == right.getCodeHandler()); handler = getCodeHandler(); } std::unique_ptr<Base> value; if (isValueDefined() && right.isValueDefined()) { value.reset(new Base(getValue() - right.getValue())); } makeVariable(*handler, new OperationNode<Base>(CGOpCode::Sub,{argument(), right.argument()}), value); } return *this; }
inline CG<Base>& CG<Base>::operator*=(const CG<Base> &right) { if (isParameter() && right.isParameter()) { *value_ *= *right.value_; } else { CodeHandler<Base>* handler; if (isParameter()) { if (isIdenticalZero()) { return *this; // nothing to do (does not consider that right might be infinity) } else if (isIdenticalOne()) { *this = right; return *this; } handler = right.getCodeHandler(); } else if (right.isParameter()) { if (right.isIdenticalZero()) { makeParameter(Base(0.0)); // does not consider that left might be infinity return *this; } else if (right.isIdenticalOne()) { return *this; // nothing to do } handler = getCodeHandler(); } else { CPPADCG_ASSERT_UNKNOWN(getCodeHandler() == right.getCodeHandler()); handler = getCodeHandler(); } std::unique_ptr<Base> value; if (isValueDefined() && right.isValueDefined()) { value.reset(new Base(getValue() * right.getValue())); } makeVariable(*handler, new OperationNode<Base>(CGOpCode::Mul,{argument(), right.argument()}), value); } return *this; }
YY_ACTION(void) yy_1_primary(char *yytext, int yyleng) { yyprintf((stderr, "do yy_1_primary\n")); push(makeVariable(yytext)); ; }
YY_ACTION(void) yy_1_primary(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) { yyprintf((stderr, "do yy_1_primary\n")); push(makeVariable(yytext)); ; }
void BuiltIns::defineBuiltIns() { auto factory = SymbolFactory{ }; auto makeRef = [](auto&& type, bool is_const) { return VariableType(TypeFactory::getReference(type.get()), is_const); }; auto global_scope = std::make_shared<GlobalScope>(); auto int_ = factory.makeStruct("int", new StructScope("int", global_scope.get())); auto ref_int = makeRef(int_, false); auto const_ref_int = makeRef(int_, true); auto char_ = factory.makeStruct("char", new StructScope("char", global_scope.get())); auto ref_char = makeRef(char_, false); auto const_ref_char = makeRef(char_, true); auto str = factory.makeStruct("string", new StructScope("string", global_scope.get())); auto ref_str = makeRef(str, false); auto const_ref_str = makeRef(str, true); auto int_builtin = VariableType(new BuiltInTypeSymbol("~~int", Comp::config().int_size), false); auto char_builtin = VariableType(new BuiltInTypeSymbol("~~char", Comp::config().int_size), false); auto simple_traits = FunctionTraits::simple(); auto op_traits = FunctionTraits::methodOper(); auto meth_traits = FunctionTraits::method(); auto constr_traits = FunctionTraits::constructor(); auto tp = FunctionType(int_.get(), {ref_int, int_.get()}); auto void_type = std::make_unique<BuiltInTypeSymbol>("void", 0); global_scope -> define(factory.makeFunction("putchar", FunctionType(void_type.get(), {char_.get()}), simple_traits, false)); global_scope -> define(factory.makeFunction("getchar", FunctionType(int_.get(), { }), simple_traits, false)); auto string_builtin = VariableType(new BuiltInTypeSymbol("~~string", 256), false); str -> defineMember(factory.makeVariable("~~impl", string_builtin, VariableSymbolType::FIELD)); auto str_tp = FunctionType(ref_str, {ref_str, const_ref_str}); int_ -> defineMember(factory.makeVariable("~~impl", int_builtin, VariableSymbolType::FIELD)); int_ -> defineMethod(factory.makeFunction("int", FunctionType(ref_int, {ref_int}), constr_traits, false)); int_ -> defineMethod(factory.makeFunction("int", FunctionType(ref_int, {ref_int, const_ref_int}), constr_traits, false)); int_ -> defineMethod(factory.makeFunction("operator=", FunctionType(ref_int, {ref_int, const_ref_int}), op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator+", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator-", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator*", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator/", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator%", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator==", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator!=", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator&&", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("operator||", tp, op_traits, false)); int_ -> defineMethod(factory.makeFunction("int", FunctionType(ref_int, {ref_int, char_.get()}), constr_traits, false)); char_ -> defineMember(factory.makeVariable("~~impl", char_builtin, VariableSymbolType::FIELD)); char_ -> defineMethod(factory.makeFunction("char", FunctionType(ref_char, {ref_char}), constr_traits, false)); char_ -> defineMethod(factory.makeFunction("char", FunctionType(ref_char, {ref_char, const_ref_char}), constr_traits, false)); char_ -> defineMethod(factory.makeFunction("char", FunctionType(ref_char, {ref_char, const_ref_int}), constr_traits, false)); char_ -> defineMethod(factory.makeFunction("operator=", FunctionType(ref_char, {ref_char, const_ref_char}), constr_traits, false)); str -> defineMethod(factory.makeFunction("string", str_tp, constr_traits, false)); str -> defineMethod(factory.makeFunction("length", FunctionType(int_.get(), {ref_str}), meth_traits, false)); str -> defineMethod(factory.makeFunction("operator[]", FunctionType(ref_char, {ref_str, int_.get()}), op_traits, false)); str -> defineMethod(factory.makeFunction("operator+", FunctionType(str.get(), {ref_str, const_ref_str}), op_traits, false)); str -> defineMethod(factory.makeFunction("operator=", str_tp, op_traits, false)); global_scope -> define(factory.makeFunction("print", FunctionType(void_type.get(), {const_ref_str}), simple_traits, false)); BuiltIns::int_type = int_.get(); BuiltIns::char_type = char_.get(); BuiltIns::ASCII_string_type = str.get(); BuiltIns::void_type = void_type.get(); global_scope -> define(std::move(void_type)); global_scope -> define(std::move(int_)); global_scope -> define(std::move(str)); global_scope -> define(std::move(char_)); BuiltIns::global_scope = global_scope; }
/** Parse with one token worth of look-ahead, return the expression object representing the syntax parsed. @param tok next token from the input. @param fp file subsequent tokens are being read from. @return the expression object constructed from the input. */ Expr *parse( char *tok, FILE *fp ) { // Create a literal token for anything that looks like a number. { long dummy; int pos; // See if the whole token parses as a long int. if ( sscanf( tok, "%ld%n", &dummy, &pos ) == 1 && pos == strlen( tok ) ) { // Copy the literal to a dynamically allocated string, since makeLiteral wants // a string it can keep. char *str = (char *) malloc( strlen( tok ) + 1 ); return makeLiteral( strcpy( str, tok ) ); } } // Create a literal token for a quoted string, without the quotes. if ( tok[ 0 ] == '"' ) { // Same as above, make a dynamically allocated copy of the token that the literal // expression can keep as long as at wants to. int len = strlen( tok ); char *str = (char *) malloc( len - 1 ); strncpy( str, tok + 1, len - 2 ); str[ len - 2 ] = '\0'; return makeLiteral( str ); } // Handle compound statements if ( strcmp( tok, "{" ) == 0 ) { int len = 0; int cap = INITIAL_CAPACITY; Expr **eList = (Expr **) malloc( cap * sizeof( Expr * ) ); // Keep parsing subexpressions until we hit the closing curly bracket. while ( strcmp( expectToken( tok, fp ), "}" ) != 0 ) { if ( len >= cap ) eList = (Expr **) realloc( eList, ( cap *= 2 ) * sizeof( Expr * ) ); eList[ len++ ] = parse( tok, fp ); } return makeCompound( eList, len ); } // Handle language operators (reserved words) if ( strcmp( tok, "print" ) == 0 ) { // Parse the one argument to print, and create a print expression. Expr *arg = parse( expectToken( tok, fp ), fp ); return makePrint( arg ); } if ( strcmp( tok, "set" ) == 0 ) { // Parse the two operands, then make a set expression with them. char *str = expectToken( tok, fp ); int len = strlen( str ); char *name = (char *) malloc( len + 1 ); strcpy( name, str ); name[ len ] = '\0'; if ( !isalpha(name[0]) || strlen( name ) > MAX_VAR || strchr( name, LEFT_BRACKET ) || strchr( name, RIGHT_BRACKET ) || strchr( name, POUND ) ) { // Complain if we can't make sense of the variable. fprintf( stderr, "line %d: invalid variable name \"%s\"\n", linesRead(), name ); exit( EXIT_FAILURE ); } Expr *expr = parse( expectToken( tok, fp ), fp ); Expr *set = makeSet ( name, expr ); free(name); return set; } if ( strcmp( tok, "add" ) == 0 ) { // Parse the two operands, then make an add expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeAdd( op1, op2 ); } if ( strcmp( tok, "sub" ) == 0 ) { // Parse the two operands, then make a sub expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeSub( op1, op2 ); } if ( strcmp( tok, "mul" ) == 0 ) { // Parse the two operands, then make a mul expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeMul( op1, op2 ); } if ( strcmp( tok, "div" ) == 0 ) { // Parse the two operands, then make a div expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeDiv ( op1, op2 ); } if ( strcmp( tok, "equal" ) == 0 ) { // Parse the two operands, then make an equal expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeEqual ( op1, op2 ); } if ( strcmp( tok, "less" ) == 0 ) { // Parse the two operands, then make a less expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeLess ( op1, op2 ); } if ( strcmp( tok, "not" ) == 0 ) { // Parse the operand, then make a not expression with it. Expr *op = parse( expectToken( tok, fp ), fp ); return makeNot ( op ); } if ( strcmp( tok, "and" ) == 0 ) { // Parse the two operands, then make an and expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeAnd ( op1, op2 ); } if ( strcmp( tok, "or" ) == 0 ) { // Parse the two operands, then make an or expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeOr ( op1, op2 ); } if ( strcmp( tok, "if" ) == 0 ) { // Parse the two operands, then make an if expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeIf ( op1, op2 ); } if ( strcmp( tok, "while" ) == 0 ) { // Parse the two operands, then make a while expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeWhile ( op1, op2 ); } if ( strcmp( tok, "concat" ) == 0 ) { // Parse the two operands, then make a concatenation expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); return makeConcat ( op1, op2 ); } if ( strcmp( tok, "substr" ) == 0 ) { // Parse the three operands, then make a substring expression with them. Expr *op1 = parse( expectToken( tok, fp ), fp ); Expr *op2 = parse( expectToken( tok, fp ), fp ); Expr *op3 = parse( expectToken( tok, fp ), fp ); return makeSubstr ( op1, op2, op3 ); } // Handle variables if ( isalpha(tok[0]) && strlen( tok ) <= MAX_VAR && !strchr( tok, LEFT_BRACKET ) && !strchr( tok, RIGHT_BRACKET ) && !strchr( tok, POUND ) ) { // Parse the variable name and make a variable expression. char *str = tok; int len = strlen( str ); char *name = (char *) malloc( len + 1 ); strcpy( name, str ); name[ len ] = '\0'; Expr *var = makeVariable( name ); free(name); return var; } // Complain if we can't make sense of the token. fprintf( stderr, "line %d: invalid token \"%s\"\n", linesRead(), tok ); exit( EXIT_FAILURE ); // Never reached. return NULL; }