PHP Parser 0.1.9
Transforms a class definition:
This wasn’t all that tricky. var needed to be converted to attr_accessor. $this-> needed to be converted to self., but otherwise, it was a very straight forward transform.
class ResultSet {
var $result;
var $total_rows;
var $fetched_rows;
function set_result( $res ) {
$this->result = $res;
}
function get_result() {
return $this->result;
}
function set_total_rows( $rows ) {
$this->total_rows = $rows;
}
function get_total_rows() {
return $this->total_rows;
}
function set_fetched_rows( $rows ) {
$this->fetched_rows = $rows;
}
function get_fetched_rows() {
return $this->fetched_rows;
}
function increment_fetched_rows() {
$this->fetched_rows = $this->fetched_rows + 1;
}
}
class ResultSet
attr_accessor(:result)
attr_accessor(:total_rows)
attr_accessor(:fetched_rows)
def set_result(res)
self.result = res
end
def get_result
return self.result
end
def set_total_rows(rows)
self.total_rows = rows
end
def get_total_rows
return self.total_rows
end
def set_fetched_rows(rows)
self.fetched_rows = rows
end
def get_fetched_rows
return self.fetched_rows
end
def increment_fetched_rows
self.fetched_rows = (self.fetched_rows + 1)
end
end
Transforms a switch case, and error guard
This one was slightly trickier. The global variable $dbtype need to be replaced throughout the AST, which ended up meaning saving a list of globals for the entire duration of the transform :(. I’d like to keep going for straight replacement transforms without keeping track of state, but some of the more complicated ASTs, along with the behavior of the Dhaka parser, kind of require it.
Specifically, the switch-case AST wasn’t all that complicated but it become a bit of a challenge with Dhaka, because there is no splat operator in it’s parser generator grammar, unlike normal BNF. So nodes would end up [:looking, [:like, [:this]] instead of [:looking, :like, :this]. This required a selective flattening operation that only applied to the statement nodes but not it’s children nodes.
Finally, to give myself an extra challenge, I added Php’s error guard, which ended up being equalvalent to Ruby’s rescue nil idiom. I prefer to use the :try idiom nowadays, but rescue nil does look pretty nice.
One flaw that I should point out is that Php’s switch-case semantics are exactly like C/C++, so the case without an statements will “fall through” to a case below it. This is not true of Ruby and will have to be finagled to produce the correct semantics, probably by joining the conditional expressions, separated by a comma.
function sql_logout($id)
{
global $dbtype;
switch ($dbtype) {
case "MySQL":
$dbi=@mysql_close($id);
return $dbi;
break;;
case "mSQL":
$dbi=@msql_close($id);
return $dbi;
break;;
case "postgres":
case "postgres_local":
$dbi=@pg_close($id);
return $dbi;
break;;
case "ODBC":
case "ODBC_Adabas":
$dbi=@odbc_close($id);
return $dbi;
break;;
case "Interbase":
$dbi=@ibase_close($id);
return $dbi;
break;;
case "Sybase":
$dbi=@sybase_close($id);
return $dbi;
break;;
default:
break;;
}
}
def sql_logout(id)
$dbtype
case $dbtype
when "MySQL" then
dbi = mysql_close(id) rescue nil
return dbi
break
when "mSQL" then
dbi = msql_close(id) rescue nil
return dbi
break
when "postgres" then
# do nothing
when "postgres_local" then
dbi = pg_close(id) rescue nil
return dbi
break
when "ODBC" then
# do nothing
when "ODBC_Adabas" then
dbi = odbc_close(id) rescue nil
return dbi
break
when "Interbase" then
dbi = ibase_close(id) rescue nil
return dbi
break
when "Sybase" then
dbi = sybase_close(id) rescue nil
return dbi
break
else
break
end
end