metal/metal_php_bindings.php - view - 1.27
<?
if(!defined("METAL_PHP_BINDINGS_INCLUDED"))
{
define("METAL_PHP_BINDINGS_INCLUDED",1);
/*
* metal_php_bindings.php
*
* @(#) $Header: /opt2/mlemos/cvs/metal/metal/metal_php_bindings.php,v 1.27 1999/10/11 18:24:57 mlemos Exp $
*
*/
class metal_php_bindings_class extends metal_base_bindings_class
{
var $last_was_command=0;
var $nesting_level=0;
var $priorities=array(
"AND"=>1,
"OR"=>1,
"LESS"=>2,
"MORE"=>2,
"EQUAL"=>2,
"DIFFERENT"=>2,
"EQUALSTRINGS"=>2,
"DIFFERENTSTRINGS"=>2,
"JOIN"=>3,
"PLUS"=>3,
"MINUS"=>3
);
Function Setup(&$compiler,&$code,&$context)
{
$this->last_was_command=0;
$this->nesting_level=0;
return(1);
}
Function EvaluateOperation(&$compiler,&$context,&$left,&$right,&$operator)
{
$left_type=$left["Data"]["Type"];
$right_type=$right["Data"]["Type"];
switch($operator["Data"])
{
case "LESS":
case "MORE":
case "EQUAL":
case "EQUALSTRINGS":
case "DIFFERENT":
case "DIFFERENTSTRINGS":
case "AND":
case "OR":
case "PLUS":
case "MINUS":
case "JOIN":
switch($operator["Data"])
{
case "LESS":
$operation="%s<%s";
$type="INTEGER";
$result_type="BOOLEAN";
break;
case "MORE":
$operation="%s>%s";
$type="INTEGER";
$result_type="BOOLEAN";
break;
case "EQUAL":
$operation="%s==%s";
$type="INTEGER";
$result_type="BOOLEAN";
break;
case "DIFFERENT":
$operation="%s!=%s";
$type="INTEGER";
$result_type="BOOLEAN";
break;
case "EQUALSTRINGS":
$operation="!strcmp(%s,%s)";
$type="STRING";
$result_type="BOOLEAN";
break;
case "DIFFERENTSTRINGS":
$operation="strcmp(%s,%s)";
$type="STRING";
$result_type="BOOLEAN";
break;
case "AND":
$operation="%s && %s";
$type=$result_type="BOOLEAN";
break;
case "OR":
$operation="%s || %s";
$type=$result_type="BOOLEAN";
break;
case "PLUS":
$operation="%s+%s";
$type=$result_type="INTEGER";
break;
case "MINUS":
$operation="%s-%s";
$type=$result_type="INTEGER";
break;
case "JOIN":
$operation="%s.%s";
$type=$result_type="STRING";
break;
}
if(!strcmp($left_type,"ANY"))
$left_type=$type;
if(!strcmp($right_type,"ANY"))
$right_type=$type;
if(strcmp($left_type,$right_type))
{
$compiler->SetElementError($context->file,$context->path,"it were specified expressions of different types of values on each side of the operator ".$operator["Data"]);
return(0);
}
if(strcmp($left_type,$type))
{
$compiler->SetElementError($context->file,$context->path,"it were specified non-$type expressions for comparision");
return(0);
}
$left["Data"]["Value"]=sprintf($operation,$left["Data"]["Value"],$right["Data"]["Value"]);
$left["Data"]["Type"]=$result_type;
$left["Data"]["Side"]="RIGHT";
break;
default:
$compiler->SetElementError($context->file,$context->path,$operator["Data"]." is not a supported OPERATOR");
return(0);
}
Unset($operator);
Unset($right);
return(1);
}
Function EvaluateExpression(&$compiler,&$context,&$expression,$position,&$result)
{
for(;$position<count($expression);$position++)
{
switch($expression[$position]["Type"])
{
case "INITIALIZATION":
case "FILE":
$context->result[]=$expression[$position];
break;
case "EXPRESSION":
if(IsSet($left))
{
if(!IsSet($operator)
|| IsSet($right))
{
$compiler->SetElementError($context->file,$context->path,"it was specified an expression with incorrect syntax");
return(0);
}
$right=$expression[$position];
$right_position=$position;
}
else
$left=$expression[$position];
break;
case "OPERATOR":
if(!IsSet($left))
{
$compiler->SetElementError($context->file,$context->path,"it was specified an operator where a expression was expected");
return(0);
}
if(!IsSet($this->priorities[$expression[$position]["Data"]]))
{
$compiler->SetElementError($context->file,$context->path,"it was specified an operator (".$expression[$position]["Data"].") with unknown priority");
return(0);
}
$new_priority=$this->priorities[$expression[$position]["Data"]];
if(IsSet($operator))
{
if(IsSet($right))
{
if($new_priority>$priority)
{
if(!$this->EvaluateExpression(&$compiler,&$context,&$expression,$right_position,&$right)
|| !$this->EvaluateOperation(&$compiler,&$context,&$left,&$right,&$operator))
return(0);
break 2;
}
else
{
if(!$this->EvaluateOperation(&$compiler,&$context,&$left,&$right,&$operator))
return(0);
$operator=$expression[$position];
$priority=$new_priority;
}
}
else
{
$compiler->SetElementError($context->file,$context->path,"it were specified two consecutive without an expression between them");
return(0);
}
}
else
{
$operator=$expression[$position];
$priority=$new_priority;
}
break;
default:
$compiler->SetElementError($context->file,$context->path,"it was specified a ".$expression[$position]["Type"]." within an expression");
return(0);
}
}
if(IsSet($right))
{
if(!IsSet($operator))
{
$compiler->SetElementError($context->file,$context->path,"it was specified an incomplete expression");
return(0);
}
if(!$this->EvaluateOperation(&$compiler,&$context,&$left,&$right,&$operator))
return(0);
}
$result=$left;
return(1);
}
Function GetExpressionValue(&$compiler,&$context,&$expression,&$expression_value,&$expression_type)
{
$result=array();
if(!$this->EvaluateExpression(&$compiler,&$context,&$expression,0,&$result))
return(0);
$expression_value=$result["Data"]["Value"];
$expression_type=$result["Data"]["Type"];
return(1);
}
Function ComposeExpression(&$compiler,&$context,$type,$side,&$expression,$error)
{
$result=array();
if(!$this->EvaluateExpression(&$compiler,&$context,&$expression,0,&$result))
return(0);
$valid_expression=1;
if(strcmp($side,"ANY")
&& strcmp($result["Data"]["Side"],"ANY"))
{
switch($side)
{
case "LEFT":
case "RIGHT":
case "BOTH":
if(strcmp($result["Data"]["Side"],$side))
$valid_expression=0;
break;
case "NOTLEFT":
if(!strcmp($result["Data"]["Side"],"LEFT"))
$valid_expression=0;
break;
case "NOTRIGHT":
if(!strcmp($result["Data"]["Side"],"RIGHT"))
$valid_expression=0;
break;
}
}
if(!$valid_expression
|| (strcmp($type,"ANY")
&& strcmp($result["Data"]["Type"],"ANY")
&& strcmp($result["Data"]["Type"],$type)))
{
$compiler->SetElementError($context->file,$context->path,$error);
return(0);
}
$context->result[]=$result;
return(1);
}
Function ConvertTypedData(&$compiler,&$context,$type,$data)
{
switch($type)
{
case "STRING":
for($converted_data="\"",$position=0;$position<strlen($data);$position++)
{
switch($character=$data[$position])
{
case "\r":
$converted_data.="\\r";
break;
case "\n":
$converted_data.="\\n";
break;
case "\t":
$converted_data.="\\t";
break;
case "\$":
$converted_data.="\\$";
break;
case "\"":
$converted_data.="\\\"";
break;
default:
$order=Ord($character);
if($order<32
|| $order>127)
$converted_data.=sprintf("\\%o",$order);
else
$converted_data.=$character;
break;
}
}
$converted_data.="\"";
break;
case "INTEGER":
if(strval(intval($data))!=$data)
{
$compiler->SetElementError($context->file,$context->path,"\"$data\" is not a valid INTEGER value");
return(0);
}
$converted_data="$data";
break;
case "BOOLEAN":
switch(strtolower($data))
{
case "1":
case "true":
$converted_data=1;
break;
case "0":
case "false":
$converted_data=0;
break;
default:
$compiler->SetElementError($context->file,$context->path,"\"$data\" is not a valid BOOLEAN value");
return(0);
}
break;
case "ASSOCIATIVEARRAY":
case "ARRAY":
if(strcmp($data,""))
{
$compiler->SetElementError($context->file,$context->path,"\"$data\" is not a valid $type value");
return(0);
}
$converted_data="array()";
break;
default:
$compiler->SetElementError($context->file,$context->path,$type." is not a valid type to be converted from data");
return(0);
}
$context->result[]=array(
"Data"=>array(
"Value"=>$converted_data,
"Type"=>$type,
"Side"=>"RIGHT"
),
"Type"=>"EXPRESSION"
);
return(1);
}
Function GenerateOutput(&$compiler,&$context,$data,&$output,$indent)
{
$output_context=$context;
$output_context->result=array();
if(!strcmp($indent,""))
$indent="\t";
for($part=0;$part<count($data);$part++)
{
switch($data[$part]["Type"])
{
case "INITIALIZATION":
$this->nesting_level++;
$initialization_context=$context;
$initialization_context->result=array();
$success=$compiler->OutputObjectInitialization(&$initialization_context,$data[$part]["Data"],&$output,$indent);
$this->nesting_level--;
if(!$success)
return(0);
for($output_part=0;$output_part<count($initialization_context->result);$output_part++)
$output_context->result[]=$initialization_context->result[$output_part];
break;
case "DATA":
if($this->last_was_command)
$output.="?>";
$output.=$data[$part]["Data"];
$this->last_was_command=0;
break;
case "COMMAND":
if(!$this->last_was_command)
$output.="<?php\n";
$output.=$indent.$data[$part]["Data"]."\n";
$this->last_was_command=1;
break;
case "EXPRESSION":
if(!$this->last_was_command)
$output.="<?php\n";
$output.=$indent."echo ".$data[$part]["Data"]["Value"].";\n";
$this->last_was_command=1;
break;
case "INDENT":
for($level=$data[$part]["Data"];$level;$indent.="\t",$level--);
break;
case "OUTDENT":
$indent=substr($indent,0,strlen($indent)-$data[$part]["Data"]);
break;
case "DEFERRED":
$command_data=$data[$part]["Data"];
$error="it was specified a misplaced ".$command_data["Command"]." command";
if(IsSet($command_data["File"])
&& IsSet($command_data["Line"])
&& IsSet($command_data["Column"])
&& IsSet($command_data["Byte"]))
$compiler->SetError($command_data["File"],$command_data["Line"],$command_data["Column"],$command_data["Byte"],$error);
else
$compiler->SetElementError($context->file,$context->path,$error);
return(0);
case "FILE":
if(!file_exists($data[$part]["Data"]["Name"]))
{
$compiler->SetElementError($context->file,$context->path,"it was specified a ".$data[$part]["Data"]["Type"]." file (\"".$data[$part]["Data"]["Name"]."\") that does not exist");
return(0);
}
$output_context->result[]=$data[$part];
break;
default:
$compiler->SetElementError($context->file,$context->path,$data[$part]["Type"]." is not a supported output type");
return(0);
}
}
if(!$this->nesting_level
&& $this->last_was_command)
{
$output.="?>";
$this->last_was_command=0;
}
$context->result=$output_context->result;
return(1);
}
};
}
?>
|