Skip to content

Instantly share code, notes, and snippets.

@haskellcamargo
Last active August 31, 2017 18:46
Show Gist options
  • Save haskellcamargo/8d73d4c7a19f45daa614 to your computer and use it in GitHub Desktop.
Save haskellcamargo/8d73d4c7a19f45daa614 to your computer and use it in GitHub Desktop.
Frankenstein - TypeScript Preprocessor
<?php
function parse($file)
{
$result_stack = [];
$tokens = token_get_all("<?php " . file_get_contents($file));
for ($i = 0, $l = sizeof($tokens); $i < $l; $i++) {
// T_OPEN
if (is_open($tokens[$i])) {
// Expect whitespace
if (token_at(T_WHITESPACE, ++$i, $tokens)) {
// Expect simple string
if (token_at(T_CONSTANT_ENCAPSED_STRING, ++$i, $tokens)) {
$reference = codegen_open(token_val($tokens[$i]));
// Expect semicolon
if (token_at(";", ++$i, $tokens)) {
$result_stack[] = $reference;
} else {
throw new Exception("Expecting semicolon in `open`.");
}
} else {
throw new Exception("Excepting filename in `open`.");
}
} else {
throw new Exception("Expecting whitespace after `open`.");
}
// T_LAMBDA
} elseif (is_lambda($tokens[$i])) {
$result_stack[] = codegen_lambda();
// T_LET
} elseif (is_let($tokens[$i])) {
$result_stack[] = codegen_let();
// T_THIS
} elseif (is_this($tokens[$i])) {
$result_stack[] = codegen_this();
// T_TYPESIG
} elseif (is_typesig($tokens[$i])) {
$result_stack[] = codegen_typesig();
} else {
$result_stack[] = $tokens[$i];
}
}
echo translate_to_source($result_stack);
}
parse($argv[1]);
function codegen_typesig()
{
return make_token(":");
}
function codegen_this()
{
return make_token("this.");
}
function codegen_let()
{
return make_token("var");
}
function codegen_lambda()
{
return make_token("() =>");
}
function codegen_open($filename)
{
return make_token("/// <reference path={$filename} />",
T_CONSTANT_ENCAPSED_STRING);
}
function token_at($token, $pos, &$stack)
{
return is_string($stack[$pos])
? $stack[$pos] === $token
: $stack[$pos][0] === $token;
}
function is_typesig($combinator)
{
return $combinator[0] === T_PAAMAYIM_NEKUDOTAYIM && $combinator[1] === "::";
}
function is_this($combinator)
{
return $combinator === "@";
}
function is_open($combinator)
{
return $combinator[0] === T_STRING && $combinator[1] === "open";
}
function is_let($combinator)
{
return $combinator[0] === T_STRING && $combinator[1] === "let";
}
function is_lambda($combinator)
{
return $combinator[0] === T_STRING && $combinator[1] === "λ";
}
function make_token($value, $key = null)
{
return isset($key)
? [$key, $value, 1]
: $value; // Literal
}
function token_val($token)
{
return is_string($token)
? $token
: $token[1];
}
function translate_to_source($stack)
{
$source = [];
for ($i = 1, $l = sizeof($stack); $i < $l; $i++) {
if (is_string($stack[$i])) {
$source[] = $stack[$i];
} else {
$source[] = $stack[$i][1];
}
}
return implode("", $source);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment