コード例 #1
0
ファイル: grokit_exprinfo.php プロジェクト: gokulp/grokit
 public function absorbMeta(ExpressionInfo &$info)
 {
     $this->constants = array_merge($this->constants, $info->constants);
     $this->preprocess = array_merge($this->preprocess, $info->preprocess);
     $this->is_const = $this->is_const && $info->is_const;
     $this->libraries = array_unique(array_merge($this->libraries, $info->libraries()));
 }
コード例 #2
0
ファイル: grokit_codegen_expr.php プロジェクト: gokulp/grokit
function parseCaseNoBase(&$source, &$cases, &$default)
{
    // The return type of the tests must be boolean
    $testRetType = lookupType('bool');
    // We don't know the return type yet, it will be defined by the cases.
    $retType = null;
    $retSource = null;
    // Generate a name for the return value of the case.
    $value_name = generate_name("case_value");
    $prep = [];
    $info = new ExpressionInfo($source, null, $value_name, true);
    grokit_logic_assert(count($cases) > 0, 'No cases found for case statement at ' . $source);
    // Handle cases
    foreach ($cases as $case) {
        $test = parseExpression(ast_get($case, NodeKey::TEST));
        $expr = parseExpression(ast_get($case, NodeKey::EXPR));
        $first = false;
        // Test if the return type of the test is compatible with boolean
        if (canConvert($test->type(), $testRetType)) {
            $test = convertExpression($test, $testRetType, $retSource);
        } else {
            // Incompatible types
            grokit_error('Case test expression has return type ' . $test->type() . ' which is incompatible with boolean ' . $test->source());
        }
        // If the return type is not set, set it and continue.
        // Otherwise, make sure the expression's return type is compatible with
        // the already set return type.
        if ($retType === null) {
            $retType = $expr->type();
            $retSource = $expr->source();
            $first = true;
            $info->setType($retType);
        } else {
            if (canConvert($expr->type(), $retType)) {
                // The types are compatible or the same, so make them the same.
                $expr = convertExpression($expr, $retType, $retSource);
            } else {
                // Incompatible types
                grokit_error('Case return type ' . $expr->type() . ' of expression at ' . $expr->source() . ' incompatible with previous return type ' . $retType . ' defined by expression at ' . $retSource);
            }
        }
        // Absorb the metadata from the test and expression into our info
        $info->absorbMeta($test);
        $info->absorbMeta($expr);
        $myPrep = '';
        if (!$first) {
            $myPrep .= 'else ';
        }
        $myPrep .= "if( {$test->value()} ) {$value_name} = {$expr->value()};";
        $prep[] = $myPrep;
    }
    // Handle default
    if ($default !== null) {
        if (canConvert($default->type(), $retType)) {
            $default = convertExpression($default, $retType, $retSource);
        } else {
            // Incompatible types.
            grokit_error('Case return type ' . $default->type() . ' of default at ' . $default->source() . ' incompatible with previous return type ' . $retType . ' defined by expression at ' . $retSource);
        }
        $info->absorbMeta($default);
        $prep[] = "else {$value_name} = {$default->value()};";
    }
    // Prepend the declaration of the return variable
    array_unshift($prep, "{$retType} {$value_name};");
    // Add all of our stuff as preprocesses
    $info->addPreprocesses($prep);
    if ($info->is_const()) {
        $info->makeConstant();
    }
    return $info;
}
コード例 #3
0
ファイル: grokit_func_info.php プロジェクト: gokulp/grokit
 public function apply($obj, array $exprs, $source)
 {
     $this->checkFuzzy($this->args, $exprs, 'parameter');
     $exprVals = array_map(function ($val) {
         return $val->value();
     }, $exprs);
     $value = $obj->value() . '.' . $this->name . '(' . implode(', ', $exprVals) . ')';
     $is_const = $this->deterministic && $obj->is_const();
     foreach ($exprs as $expr) {
         $is_const = $is_const && $expr->is_const();
     }
     $retType = lookupType($this->resultType);
     $info = new ExpressionInfo($source, $retType, $value, $is_const);
     $info->absorbMeta($obj);
     foreach ($exprs as $expr) {
         $info->absorbMeta($expr);
     }
     return $info;
 }