pull/1/head
韩天峰 8 months ago
parent ec25a3cbf0
commit bb10e4c6f2
  1. 15
      examples/array_get.php
  2. 17
      examples/c/fib.c
  3. 19
      examples/fib.php
  4. 2
      main.php
  5. 38
      src/Php/Translator.php

@ -0,0 +1,15 @@
<?php
//$array = [1, 3, 4, 5, 6];
//
//var_dump($array[2.3]);
//
//var_dump($array['3.2']);
//
//$str = "hello world\n";
//var_dump($str[99]);
//var_dump($str[-3]);
$o = new ArrayObject();
$o['hello'] = 'world';
var_dump($o['hello'], $o);

@ -0,0 +1,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int fib(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fib(n - 1) + fib(n - 2);
}
}
int main(int argc, char **argv) {
long long n = atoi(argv[1]);
printf("斐波那契数列的第%d项是:%d\n", n, fib(n));
return 0;
}

@ -0,0 +1,19 @@
<?php
function main()
{
global $argv;
$n = $argv[2];
$begin = microtime(true);
echo fib($n) . "\n";
echo "Time: " . (microtime(true) - $begin) . "\n";
}
function fib(int $n): int
{
if ($n == 1 || $n == 2) {
return 1;
} else {
return fib($n - 1) + fib($n - 2);
}
}

@ -1,3 +1,3 @@
<?php <?php
include __DIR__ . '/examples/pi.php'; include __DIR__ . '/examples/' . $argv[1];
main(); main();

@ -35,6 +35,7 @@ class Translator extends \PhpAot\Core\Translator
protected string $namespace = ''; protected string $namespace = '';
protected array $uses = []; protected array $uses = [];
protected string $class = ''; protected string $class = '';
protected string $returnType = '';
const PREFIX = 'php_'; const PREFIX = 'php_';
@ -129,18 +130,18 @@ class Translator extends \PhpAot\Core\Translator
$name = implode('__', array_reverse($names)); $name = implode('__', array_reverse($names));
if ($v->returnType) { if ($v->returnType) {
$returnType = $this->getZendType($this->parseIdentifier($v->returnType)); $this->returnType = $this->getZendType($this->parseIdentifier($v->returnType));
} else { } else {
$returnType = 'void'; $this->returnType = 'void';
} }
$params = $this->parseParams($v->params); $params = $this->parseParams($v->params);
$code = $returnType . ' ' . self::PREFIX . $name . '(' . $params . ') {' . PHP_EOL; $code = $this->returnType . ' ' . self::PREFIX . $name . '(' . $params . ') {' . PHP_EOL;
$this->indentLevel++; $this->indentLevel++;
$stmts = $this->parseStmts($v->stmts); $stmts = $this->parseStmts($v->stmts);
$this->indentLevel--; $this->indentLevel--;
$code .= $stmts; $code .= $stmts;
$code .= "}"; $code .= "}\n";
return $code; return $code;
} }
@ -215,6 +216,9 @@ class Translator extends \PhpAot\Core\Translator
case 'Stmt_Continue': case 'Stmt_Continue':
$lines[] = 'continue;'; $lines[] = 'continue;';
break; break;
case 'Stmt_Global':
$lines[] = $this->parseGlobal($v);
break;
default: default:
debug($v); debug($v);
} }
@ -367,7 +371,14 @@ class Translator extends \PhpAot\Core\Translator
private function parseReturn(mixed $v): string private function parseReturn(mixed $v): string
{ {
return 'return ' . $this->parseExpr($v->expr); $type = $this->detectType($v->expr);
$expr = $this->parseExpr($v->expr);
if ($this->returnType == self::TYPE_INT and $type == self::TYPE_VAR) {
return 'return (' . $expr . ').toInt()';
} elseif ($this->returnType == self::TYPE_FLOAT and $type == self::TYPE_VAR) {
return 'return (' . $expr . ').toFloat()';
}
return 'return ' . $expr;
} }
private function parseBinaryOpMul(mixed $expr): string private function parseBinaryOpMul(mixed $expr): string
@ -378,7 +389,7 @@ class Translator extends \PhpAot\Core\Translator
return '(' . $left . ') * (' . $right . ')'; return '(' . $left . ') * (' . $right . ')';
} }
private function detectType($var, $expr): string private function detectType($expr): string
{ {
$exprType = $expr->getType(); $exprType = $expr->getType();
switch ($exprType) { switch ($exprType) {
@ -393,8 +404,8 @@ class Translator extends \PhpAot\Core\Translator
case 'Expr_Array': case 'Expr_Array':
return 'php::Array'; return 'php::Array';
case 'Expr_BinaryOp_Plus': case 'Expr_BinaryOp_Plus':
$leftType = $this->detectType($var, $expr->left); $leftType = $this->detectType($expr->left);
$rightType = $this->detectType($var, $expr->right); $rightType = $this->detectType($expr->right);
if ($leftType === self::TYPE_INT || $rightType === self::TYPE_INT) { if ($leftType === self::TYPE_INT || $rightType === self::TYPE_INT) {
return self::TYPE_INT; return self::TYPE_INT;
} else { } else {
@ -563,7 +574,7 @@ class Translator extends \PhpAot\Core\Translator
{ {
$var = $this->parseIdentifier($node->var); $var = $this->parseIdentifier($node->var);
$dim = $this->parseIdentifier($node->dim); $dim = $this->parseIdentifier($node->dim);
return $var . '[' . $dim . ']'; return $var . '.offsetGet(' . $dim . ')';
} }
private function parseBinaryOpShiftLeft($node): string private function parseBinaryOpShiftLeft($node): string
@ -974,4 +985,13 @@ class Translator extends \PhpAot\Core\Translator
{ {
return '"' . $this->escapeString($expr->value) . '"'; return '"' . $this->escapeString($expr->value) . '"';
} }
private function parseGlobal(Node $v): string
{
$out = [];
foreach ($v->vars as $v) {
$out [] = self::TYPE_VAR . ' ' . $v->name . ' = php::global("' . $v->name . '");';
}
return implode(PHP_EOL . $this->getIndent(), $out);
}
} }

Loading…
Cancel
Save