titanscssc::compileChild PHP Method

compileChild() protected method

return a value to halt execution
protected compileChild ( $child, $out )
    protected function compileChild($child, $out)
    {
        $this->sourcePos = isset($child[-1]) ? $child[-1] : -1;
        $this->sourceParser = isset($child[-2]) ? $child[-2] : $this->parser;
        switch ($child[0]) {
            case "import":
                list(, $rawPath) = $child;
                $rawPath = $this->reduce($rawPath);
                if (!$this->compileImport($rawPath, $out)) {
                    $out->lines[] = "@import " . $this->compileValue($rawPath) . ";";
                }
                break;
            case "directive":
                list(, $directive) = $child;
                $s = "@" . $directive->name;
                if (!empty($directive->value)) {
                    $s .= " " . $this->compileValue($directive->value);
                }
                $this->compileNestedBlock($directive, array($s));
                break;
            case "media":
                $this->compileMedia($child[1]);
                break;
            case "block":
                $this->compileBlock($child[1]);
                break;
            case "charset":
                $out->lines[] = "@charset " . $this->compileValue($child[1]) . ";";
                break;
            case "assign":
                list(, $name, $value) = $child;
                if ($name[0] == "var") {
                    $isDefault = !empty($child[3]);
                    if ($isDefault) {
                        $existingValue = $this->get($name[1], true);
                        $shouldSet = $existingValue === true || $existingValue == self::$null;
                    }
                    if (!$isDefault || $shouldSet) {
                        $this->set($name[1], $this->reduce($value));
                    }
                    break;
                }
                // if the value reduces to null from something else then
                // the property should be discarded
                if ($value[0] != "null") {
                    $value = $this->reduce($value);
                    if ($value[0] == "null") {
                        break;
                    }
                }
                $compiledValue = $this->compileValue($value);
                $out->lines[] = $this->formatter->property($this->compileValue($name), $compiledValue);
                break;
            case "comment":
                $out->lines[] = $child[1];
                break;
            case "mixin":
            case "function":
                list(, $block) = $child;
                $this->set(self::$namespaces[$block->type] . $block->name, $block);
                break;
            case "extend":
                list(, $selectors) = $child;
                foreach ($selectors as $sel) {
                    // only use the first one
                    $sel = current($this->evalSelector($sel));
                    $this->pushExtends($sel, $out->selectors);
                }
                break;
            case "if":
                list(, $if) = $child;
                if ($this->isTruthy($this->reduce($if->cond, true))) {
                    return $this->compileChildren($if->children, $out);
                } else {
                    foreach ($if->cases as $case) {
                        if ($case->type == "else" || $case->type == "elseif" && $this->isTruthy($this->reduce($case->cond))) {
                            return $this->compileChildren($case->children, $out);
                        }
                    }
                }
                break;
            case "return":
                return $this->reduce($child[1], true);
            case "each":
                list(, $each) = $child;
                $list = $this->coerceList($this->reduce($each->list));
                foreach ($list[2] as $item) {
                    $this->pushEnv();
                    $this->set($each->var, $item);
                    // TODO: allow return from here
                    $this->compileChildren($each->children, $out);
                    $this->popEnv();
                }
                break;
            case "while":
                list(, $while) = $child;
                while ($this->isTruthy($this->reduce($while->cond, true))) {
                    $ret = $this->compileChildren($while->children, $out);
                    if ($ret) {
                        return $ret;
                    }
                }
                break;
            case "for":
                list(, $for) = $child;
                $start = $this->reduce($for->start, true);
                $start = $start[1];
                $end = $this->reduce($for->end, true);
                $end = $end[1];
                $d = $start < $end ? 1 : -1;
                while (true) {
                    if (!$for->until && $start - $d == $end || $for->until && $start == $end) {
                        break;
                    }
                    $this->set($for->var, array("number", $start, ""));
                    $start += $d;
                    $ret = $this->compileChildren($for->children, $out);
                    if ($ret) {
                        return $ret;
                    }
                }
                break;
            case "nestedprop":
                list(, $prop) = $child;
                $prefixed = array();
                $prefix = $this->compileValue($prop->prefix) . "-";
                foreach ($prop->children as $child) {
                    if ($child[0] == "assign") {
                        array_unshift($child[1][2], $prefix);
                    }
                    if ($child[0] == "nestedprop") {
                        array_unshift($child[1]->prefix[2], $prefix);
                    }
                    $prefixed[] = $child;
                }
                $this->compileChildren($prefixed, $out);
                break;
            case "include":
                // including a mixin
                list(, $name, $argValues, $content) = $child;
                $mixin = $this->get(self::$namespaces["mixin"] . $name, false);
                if (!$mixin) {
                    $this->throwError("Undefined mixin {$name}");
                }
                $callingScope = $this->env;
                // push scope, apply args
                $this->pushEnv();
                if ($this->env->depth > 0) {
                    $this->env->depth--;
                }
                if (!is_null($content)) {
                    $content->scope = $callingScope;
                    $this->setRaw(self::$namespaces["special"] . "content", $content);
                }
                if (!is_null($mixin->args)) {
                    $this->applyArguments($mixin->args, $argValues);
                }
                foreach ($mixin->children as $child) {
                    $this->compileChild($child, $out);
                }
                $this->popEnv();
                break;
            case "mixin_content":
                $content = $this->get(self::$namespaces["special"] . "content");
                if (is_null($content)) {
                    $this->throwError("Expected @content inside of mixin");
                }
                $strongTypes = array('include', 'block', 'for', 'while');
                foreach ($content->children as $child) {
                    $this->storeEnv = in_array($child[0], $strongTypes) ? null : $content->scope;
                    $this->compileChild($child, $out);
                }
                unset($this->storeEnv);
                break;
            case "debug":
                list(, $value, $pos) = $child;
                $line = $this->parser->getLineNo($pos);
                $value = $this->compileValue($this->reduce($value, true));
                fwrite(STDERR, "Line {$line} DEBUG: {$value}\n");
                break;
            default:
                $this->throwError("unknown child type: {$child['0']}");
        }
    }
titanscssc