<?
if(!defined("METAL_CLASS_INCLUDED"))
{
define("METAL_CLASS_INCLUDED",1);
/*
* metal_class.php
*
* @(#) $Header: /opt2/mlemos/cvs/metal/metal/metal_class.php,v 1.53 2001/06/09 22:22:23 mlemos Exp $
*
*/
class metal_class_class extends metal_base_class
{
var $classes=array();
var $subclasses=array();
var $current_class=0;
var $current_function="";
var $current_argument="";
var $current_argument_number=0;
var $current_variable="";
var $current_subclass=0;
Function GetDocumentation(&$scope,&$compiler,&$code,&$attributes,$element_path)
{
Unset($idiom);
$documentation=array();
$documentation_elements=$code->structure[$element_path]["Elements"];
for($documentation_element=0;$documentation_element<$documentation_elements;$documentation_element++)
{
$documentation_element_path=$element_path.",$documentation_element";
$data=$code->structure[$documentation_element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "idiom":
if(IsSet($idiom))
{
$compiler->SetElementError($attributes->file,$documentation_element_path,"it was defined the documentation idiom more than once");
return(0);
}
if(!$compiler->GetValidName($attributes->file,$documentation_element_path,&$idiom,"it was not specified a valid class documentation idiom option"))
return(0);
if(IsSet($scope["documentation"][$idiom]))
{
$compiler->SetElementError($attributes->file,$documentation_element_path,"it was specified the idiom of an already defined class documentation section");
return(0);
}
break;
default:
if(IsSet($documentation[$data["Tag"]]))
{
$compiler->SetElementError($attributes->file,$documentation_element_path,"it was specified the documentation tag ".$data["Tag"]." more than once");
return(0);
}
$compiler->CopyEmptyContext(&$attributes,&$documentation[$data["Tag"]]);
$documentation[$data["Tag"]]->path=$documentation_element_path;
break;
}
}
else
{
if(!$compiler->CheckWhiteSpace($attributes->file,$data,$documentation_element_path))
return(0);
}
}
if(!IsSet($idiom))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not defined the class documentation idiom");
return(0);
}
$scope["documentation"][$idiom]=$documentation;
return(1);
}
Function SetupClass(&$compiler,&$code,&$attributes)
{
$index=count($this->classes);
$this->classes[$index]["function_name"]="";
$this->classes[$index]["return_type"]="";
$this->classes[$index]["return_value_set"]=0;
$this->classes[$index]["staticload"]=0;
$this->classes[$index]["types"]=array();
$this->classes[$index]["functions"]=array();
$this->classes[$index]["variables"]=array();
$this->classes[$index]["declarationfile"]=$attributes->file;
$this->classes[$index]["declarationpath"]=$attributes->path;
$parent=0;
$elements=$code->structure[$attributes->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$attributes->path.",$element";
$data=$code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "parent":
if(!$compiler->GetValidName($attributes->file,$element_path,&$parent_name,"it was not specified a valid class parent name argument"))
return(0);
if(count($this->classes[$index]["functions"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was attempted to define the name of the parent class after having declared class functions");
return(0);
}
if(count($this->classes[$index]["variables"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was attempted to define the name of the parent class after having declared class variables");
return(0);
}
if(!IsSet($this->subclasses[$parent_name]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not specified the name of an existing parent class");
return(0);
}
if($parent==$index)
{
$compiler->SetElementError($attributes->file,$element_path,"it was not specified that the parent class is the class itself");
return(0);
}
$parent=$this->subclasses[$parent_name];
break;
case "name":
if(IsSet($this->classes[$index]["name"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was defined the class name more than once");
return(0);
}
if(!$compiler->GetValidName($attributes->file,$element_path,&$class_name,"it was not specified a valid class name argument"))
return(0);
if(IsSet($this->subclasses[$class_name]))
{
if(!strcmp($this->classes[$this->subclasses[$class_name]]["declarationfile"],$attributes->file)
&& !strcmp($this->classes[$this->subclasses[$class_name]]["declarationpath"],$attributes->path))
{
Unset($this->classes[$index]);
return(1);
}
$compiler->SetElementError($attributes->file,$element_path,"it was specified a subclass name (\"$class_name\") of an existing class");
return(0);
}
$this->classes[$index]["name"]=$class_name;
$this->subclasses[$class_name]=$index;
break;
case "function":
Unset($name);
$function=array();
$function_elements=$code->structure[$element_path]["Elements"];
for($function_element=0;$function_element<$function_elements;$function_element++)
{
$function_element_path=$element_path.",$function_element";
$data=$code->structure[$function_element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "name":
if(IsSet($name))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function name more than once");
return(0);
}
if(!$compiler->GetValidName($attributes->file,$function_element_path,&$name,"it was not specified a valid class function name option"))
return(0);
if(IsSet($this->classes[$index]["functions"][$name]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was specified a name of an already defined class function");
return(0);
}
if(IsSet($this->classes[$index]["variables"][$name]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was specified the same name for a class variable and a class function");
return(0);
}
if($index)
{
for($class_parent=$parent;;$class_parent=$this->classes[$class_parent]["parent"])
{
if(IsSet($this->classes[$class_parent]["functions"][$name]))
{
$function["type"]=$this->classes[$class_parent]["functions"][$name]["type"];
if(IsSet($this->classes[$class_parent]["functions"][$name]["Arguments"]))
$function["Arguments"]=$this->classes[$class_parent]["functions"][$name]["Arguments"];
break;
}
if(!IsSet($this->classes[$class_parent]["parent"]))
break;
}
}
break;
case "type":
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function return type before specifying its name");
return(0);
}
if($index
&& IsSet($this->classes[$parent]["functions"][$name]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was attempted to redefine the class return type of a inherited subclass function");
return(0);
}
if(IsSet($function["type"]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function type more than once");
return(0);
}
if(!$compiler->GetValidData($attributes->file,$function_element_path,&$function["type"],"it was not specified a valid class function type option"))
return(0);
switch($function["type"])
{
case "VOID":
case "STRING":
case "INTEGER":
case "FLOAT":
case "BOOLEAN":
case "OBJECT":
case "ARRAY":
case "HASH":
break;
default:
$compiler->SetElementError($attributes->file,$function_element_path,"it was not defined a valid class function return type");
return(0);
}
break;
case "private":
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function private status before specifying its name");
return(0);
}
if($index
&& IsSet($this->classes[$parent]["functions"][$name]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was attempted to redefine the class private status of a inherited subclass function");
return(0);
}
if(IsSet($function["private"]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function private status more than once");
return(0);
}
$function["private"]=1;
break;
case "argument":
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function argument before specifying its name");
return(0);
}
if($index
&& IsSet($this->classes[$parent]["functions"][$name]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was attempted to redefine a class argument of a inherited subclass function");
return(0);
}
Unset($argument_name);
$argument=array();
$argument_elements=$code->structure[$function_element_path]["Elements"];
for($argument_element=0;$argument_element<$argument_elements;$argument_element++)
{
$argument_element_path=$function_element_path.",$argument_element";
$data=$code->structure[$argument_element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "name":
if(IsSet($argument_name))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was defined the class function argument name more than once");
return(0);
}
if(!$compiler->GetValidName($attributes->file,$argument_element_path,&$argument_name,"it was not specified a valid class function argument name option"))
return(0);
if(IsSet($function["Arguments"][$argument_name]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was specified a name of an already defined class function argument");
return(0);
}
break;
case "type":
if(IsSet($argument["type"]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was defined the class function argument type more than once");
return(0);
}
if(!$compiler->GetValidData($attributes->file,$argument_element_path,&$argument["type"],"it was not specified a valid class function type option"))
return(0);
switch($argument["type"])
{
case "STRING":
case "INTEGER":
case "FLOAT":
case "BOOLEAN":
case "OBJECT":
case "ARRAY":
case "HASH":
break;
default:
$compiler->SetElementError($attributes->file,$argument_element_path,"it was not defined a valid class function argument type");
return(0);
}
break;
case "defaultvalue":
if(IsSet($argument["defaultvalue"]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was defined the class function argument defaultvalue more than once");
return(0);
}
if(IsSet($argument["reference"]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was defined a defaultvalue for a class function argument to be passed by reference");
return(0);
}
if(!IsSet($argument["type"]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was not defined the class function argument type before defining the defaultvalue");
return(0);
}
if(!$compiler->GetValidData($attributes->file,$argument_element_path,&$argument["defaultvalue"],"it was not specified a valid class argument defaultvalue option")
|| !$compiler->ConvertData(&$attributes,$argument["type"],$argument["defaultvalue"],&$argument["converteddefaultvalue"]))
return(0);
break;
case "reference":
if(IsSet($argument["reference"]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was defined the class function argument reference more than once");
return(0);
}
if(IsSet($argument["defaultvalue"]))
{
$compiler->SetElementError($attributes->file,$argument_element_path,"it was defined a defaultvalue for a class function argument to be passed by reference");
return(0);
}
$argument["reference"]=1;
break;
case "documentation":
if(!$this->GetDocumentation(&$argument,&$compiler,&$code,&$attributes,$argument_element_path))
return(0);
break;
default:
$compiler->SetElementError($attributes->file,$argument_element_path,$data["Tag"]." is not a supported class function argument attribute");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($attributes->file,$data,$argument_element_path))
return(0);
}
}
if(!IsSet($argument_name))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was not defined the class function argument name");
return(0);
}
if(!IsSet($argument["type"]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was not defined the class function argument type");
return(0);
}
$function["Arguments"][$argument_name]=$argument;
break;
case "do":
if(IsSet($function["do"]))
{
$compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function do statements more than once");
return(0);
}
$function["do"]=array(
"file"=>$attributes->file,
"path"=>$function_element_path
);
$this->classes[$index]["functions"][$name]=$function;
break;
case "documentation":
if(!$this->GetDocumentation(&$function,&$compiler,&$code,&$attributes,$function_element_path))
return(0);
break;
default:
$compiler->SetElementError($attributes->file,$function_element_path,$data["Tag"]." is not a supported class object attribute");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($attributes->file,$data,$function_element_path))
return(0);
}
}
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not defined the class function name");
return(0);
}
if(!IsSet($function["type"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not defined the class function return type");
return(0);
}
if(!IsSet($function["do"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not defined the class function do statmemnts");
return(0);
}
break;
case "variable":
if(count($this->classes[$index]["functions"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was attempted to define a class variable after having declared class functions");
return(0);
}
Unset($name);
$variable=array();
$variable_elements=$code->structure[$element_path]["Elements"];
for($variable_element=0;$variable_element<$variable_elements;$variable_element++)
{
$variable_element_path=$element_path.",$variable_element";
$data=$code->structure[$variable_element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "name":
if(IsSet($name))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable name more than once");
return(0);
}
if(!$compiler->GetValidName($attributes->file,$variable_element_path,&$name,"it was not specified a valid class variable name option"))
return(0);
if(IsSet($this->classes[$index]["variables"][$name]))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was specified a name of an already defined class variable");
return(0);
}
if($index
&& IsSet($this->classes[$parent]["variables"][$name]))
$variable["type"]=$this->classes[$parent]["variables"][$name]["type"];
break;
case "type":
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable type before specifying its name");
return(0);
}
$class=$parent;
if($this->InheritedVariableClass(&$class,$name))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was attempted to redefine the type of a inherited subclass variable");
return(0);
}
if(IsSet($variable["type"]))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable type more than once");
return(0);
}
if(!$compiler->GetValidData($attributes->file,$variable_element_path,&$variable["type"],"it was not specified a valid class variable type option"))
return(0);
switch($variable["type"])
{
case "STRING":
case "INTEGER":
case "FLOAT":
case "BOOLEAN":
case "OBJECT":
case "ARRAY":
case "HASH":
break;
default:
$compiler->SetElementError($attributes->file,$variable_element_path,"it was not defined a valid class variable type");
return(0);
}
break;
case "private":
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable private status before specifying its name");
return(0);
}
$class=$parent;
if($this->InheritedVariableClass(&$class,$name))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was attempted to redefine the private status of a inherited subclass variable");
return(0);
}
if(IsSet($variable["private"]))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable private status more than once");
return(0);
}
$variable["private"]=1;
break;
case "value":
$class=$parent;
if($this->InheritedVariableClass(&$class,$name))
$type=$this->classes[$class]["variables"][$name]["type"];
else
{
if(!IsSet($variable["type"]))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined a class variable value before specifying the variable type");
return(0);
}
$type=$variable["type"];
}
if(IsSet($variable["value"]))
{
$compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable initial value more than once");
return(0);
}
if(!$compiler->GetValidData($attributes->file,$variable_element_path,&$variable["value"],"it was not specified a valid class variable value option")
|| !$compiler->ConvertData(&$attributes,$type,$variable["value"],&$variable["convertedvalue"]))
return(0);
break;
case "documentation";
if(!$this->GetDocumentation(&$variable,&$compiler,&$code,&$attributes,$variable_element_path))
return(0);
break;
default:
$compiler->SetElementError($attributes->file,$variable_element_path,$data["Tag"]." is not a supported class object variable attribute");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($attributes->file,$data,$variable_element_path))
return(0);
}
}
if(!IsSet($name))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not defined the class variable name");
return(0);
}
$class=$parent;
if(!$this->InheritedVariableClass(&$class,$name)
&& !IsSet($variable["type"]))
{
$compiler->SetElementError($attributes->file,$element_path,"it was not defined the class variable type");
return(0);
}
$this->classes[$index]["variables"][$name]=$variable;
break;
case "file":
case "basepath":
case "tag":
case "comment":
case "copyright":
case "title":
case "author":
case "authoraddress":
if(!$compiler->GetValidData($attributes->file,$element_path,&$this->classes[$index][$data["Tag"]],"it was not specified a valid class ".$data["Tag"]." property"))
return(0);
break;
case "documentation":
if(!$this->GetDocumentation(&$this->classes[$index],&$compiler,&$code,&$attributes,$element_path))
return(0);
break;
default:
$compiler->SetElementError($attributes->file,$element_path,$data["Tag"]." is not a supported class object class attribute");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($attributes->file,$data,$element_path))
return(0);
}
}
if(!IsSet($this->classes[$index]["name"]))
{
if($index)
{
$compiler->SetElementError($attributes->file,$attributes->path,"it was not specified the class name");
return(0);
}
else
{
$this->classes[$index]["name"]=$this->object_name;
$this->subclasses[$this->object_name]=$index;
}
}
if($index)
$this->classes[$index]["parent"]=$parent;
if(!IsSet($this->classes[$index]["tag"]))
$this->classes[$index]["tag"]="CLASS_".strtoupper(ereg_replace("[^A-Za-z0-9]","_",$this->classes[$index]["file"]));
return(1);
}
Function Setup(&$compiler,&$code,&$attributes)
{
$elements=$code->structure[$attributes->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$attributes->path.",$element";
$data=$code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "class":
if(count($this->classes))
{
$compiler->SetElementError($attributes->file,$element_path,"it was attempted to redefine the base class");
return(0);
}
$class_attributes=$attributes;
$class_attributes->path=$element_path;
if(!$this->SetupClass(&$compiler,&$code,&$class_attributes))
return(0);
break;
default:
$compiler->SetElementError($attributes->file,$element_path,$data["Tag"]." is not a supported class object attribute");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($attributes->file,$data,$element_path))
return(0);
}
}
return(1);
}
Function InheritedFunctionClass(&$class,$function)
{
for(;;$class=$this->classes[$class]["parent"])
{
if(IsSet($this->classes[$class]["functions"][$function]))
return(1);
if($class==0)
return(0);
}
}
Function InheritedVariableClass(&$class,$variable)
{
for(;;$class=$this->classes[$class]["parent"])
{
if(IsSet($this->classes[$class]["variables"][$variable]))
return(1);
if($class==0)
return(0);
}
}
Function Call(&$compiler,&$code,&$context,&$call,$function)
{
$class=$subclass=(IsSet($call["subclass"]) ? $call["subclass"] : $this->current_subclass);
$elements=$code->structure[$context->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$context->path.",$element";
$data=$code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "subclass":
if(count($call))
{
$compiler->SetElementError($context->file,$element_path,"it was specified the class $function subclass argument after having specified other arguments");
return(0);
}
if(!$this->GetSubclassArgument(&$compiler,$context->file,$element_path,&$call))
return(0);
$subclass=$call["subclass"];
break;
case "function":
$argument=$data["Tag"];
if(IsSet($call[$argument]))
{
$compiler->SetElementError($context->file,$element_path,"it was specified the class $function $argument argument more than once");
return(0);
}
if(!$compiler->GetValidData($context->file,$element_path,&$call["function"],"it was not specified a valid class $function function argument"))
return(0);
$class=$subclass;
if(!$this->InheritedFunctionClass(&$class,$call["function"]))
{
$compiler->SetElementError($context->file,$element_path,"it was requested to $function a class function (\"".$call["function"]."\") that was not defined");
return(0);
}
break;
case "arguments":
if(!IsSet($call["function"]))
{
$compiler->SetElementError($context->file,$element_path,"it was not defined the function to call before specifying the $function arguments");
return(0);
}
if(!IsSet($this->classes[$class]["functions"][$call["function"]]["Arguments"]))
{
$compiler->SetElementError($context->file,$element_path,"the specified function to $function does not take any arguments");
return(0);
}
$function_arguments=$this->classes[$class]["functions"][$call["function"]]["Arguments"];
$argument_elements=$code->structure[$element_path]["Elements"];
for($argument_element=0;$argument_element<$argument_elements;$argument_element++)
{
$argument_element_path=$element_path.",$argument_element";
$data=$code->structure[$argument_element_path];
if(GetType($data)=="array")
{
if(!IsSet($function_arguments[$data["Tag"]]))
{
$compiler->SetElementError($context->file,$argument_element_path,"it was not specified a valid $function function argument");
return(0);
}
if(IsSet($call["arguments"][$data["Tag"]]))
{
$compiler->SetElementError($context->file,$argument_element_path,"it was specified the ".$data["Tag"]." $function function argument more than once");
return(0);
}
$call["arguments"][$data["Tag"]]=array(
"file"=>$context->file,
"path"=>$argument_element_path,
"type"=>$function_arguments[$data["Tag"]]["type"]
);
}
else
{
if(!$compiler->CheckWhiteSpace($context->file,$data,$argument_element_path))
return(0);
}
}
break;
case "object":
if(strcmp($function,"instancecall"))
{
$argument=$data["Tag"];
if(IsSet($call[$argument]))
{
$compiler->SetElementError($context->file,$element_path,"it was specified the class $function $argument argument more than once");
return(0);
}
$evaluate_context=$context;
$evaluate_context->path=$element_path;
if(!$compiler->GetValidExpression(&$evaluate_context,"OBJECT","NOTRIGHT","it was not specified a valid class object expression",1)
|| !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$call["object"],&$expression_type))
return(0);
break;
}
default:
$compiler->SetElementError($context->file,$element_path,$data["Tag"]." is not a supported class $function argument");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($context->file,$data,$element_path))
return(0);
}
}
return(1);
}
Function GenerateFunction(&$compiler,$class,$name)
{
if(!IsSet($this->classes[$class]["functions"][$name]["do"]["code"]))
{
$this->classes[$class]["functions"][$name]["do"]["code"]=array();
$function_name=$this->classes[$class]["function_name"];
$return_type=$this->classes[$class]["return_type"];
$return_value_set=$this->classes[$class]["return_value_set"];
$this->classes[$class]["function_name"]=$name;
$this->classes[$class]["return_type"]=$this->classes[$class]["functions"][$name]["type"];
$this->classes[$class]["return_value_set"]=0;
$action_context=new metal_execution_context_class;
$action_context->file=$this->classes[$class]["functions"][$name]["do"]["file"];
$action_context->path=$this->classes[$class]["functions"][$name]["do"]["path"];
$action_context->result=array();
$functions=array(
"instancevariable",
"instancecall",
"functionargument",
"return"
);
if(!$compiler->AddContextFunctions(&$action_context,$this->object_name,&$functions,&$level))
return(0);
$current_subsclass=$this->current_subclass;
$this->current_subclass=$class;
if(!$compiler->GetOutputData($this->classes[$class]["functions"][$name]["do"]["file"],$this->classes[$class]["functions"][$name]["do"]["path"],&$this->classes[$class]["functions"][$name]["do"]["code"],"it were not defined valid class function do statements",1))
return(0);
$this->current_subclass=$current_subsclass;
if(!$compiler->RemoveContextFunctions(&$action_context,$this->object_name,$level))
return(0);
if(strcmp($this->classes[$class]["functions"][$name]["type"],"VOID")
&& $this->classes[$class]["return_value_set"]==0)
{
$compiler->SetElementError($this->classes[$class]["functions"][$name]["do"]["file"],$this->classes[$class]["functions"][$name]["do"]["path"],"it was not set the class function return value");
return(0);
}
$this->classes[$class]["function_name"]=$function_name;
$this->classes[$class]["return_type"]=$return_type;
$this->classes[$class]["return_value_set"]=$return_value_set;
}
return(1);
}
Function GenerateComment($comment,&$result)
{
for($line=$comment;strcmp($line,"");)
{
$line=strtok($line,"\r\n");
$result[]=array(
"Data"=>" * $line",
"Type"=>"COMMAND"
);
$line=strtok("");
}
}
Function GenerateVariables(&$result,$class,$private)
{
for($output_variable=0,Reset($this->classes[$class]["variables"]),$function=0;$function<count($this->classes[$class]["variables"]);$function++,Next($this->classes[$class]["variables"]))
{
$name=Key($this->classes[$class]["variables"]);
if(($private
&& IsSet($this->classes[$class]["variables"][$name]["private"]))
|| (!$private
&& !IsSet($this->classes[$class]["variables"][$name]["private"])))
{
if($output_variable==0)
{
if(!$private)
{
$result[]=array(
"Data"=>"",
"Type"=>"COMMAND"
);
}
$result[]=array(
"Data"=>"/*",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" * ".($private ? "Private variables" : "Public variables"),
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" *",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" */",
"Type"=>"COMMAND"
);
}
$value=(IsSet($this->classes[$class]["variables"][$name]["value"]) ? "=".$this->classes[$class]["variables"][$name]["convertedvalue"] : "");
$result[]=array(
"Data"=>"var \$$name$value;",
"Type"=>"COMMAND"
);
$output_variable++;
}
}
}
Function GenerateFunctions(&$compiler,&$result,$class,$private)
{
for($output_function=0,Reset($this->classes[$class]["functions"]),$function=0;$function<count($this->classes[$class]["functions"]);$function++,Next($this->classes[$class]["functions"]))
{
$name=Key($this->classes[$class]["functions"]);
if(($private
&& IsSet($this->classes[$class]["functions"][$name]["private"]))
|| (!$private
&& !IsSet($this->classes[$class]["functions"][$name]["private"])))
{
$result[]=array(
"Data"=>"",
"Type"=>"COMMAND"
);
if($output_function==0)
{
$result[]=array(
"Data"=>"/*",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" * ".($private ? "Private functions" : "Public functions"),
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" *",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" */",
"Type"=>"COMMAND"
);
}
if(!$this->GenerateFunction(&$compiler,$class,$name))
return(0);
$argument_list="";
if(IsSet($this->classes[$class]["functions"][$name]["Arguments"]))
{
$arguments=$this->classes[$class]["functions"][$name]["Arguments"];
for(Reset($arguments),$argument=0;$argument<count($arguments);Next($arguments),$argument++)
{
if($argument>0)
$argument_list.=",";
$argument_list.=(IsSet($arguments[Key($arguments)]["reference"]) ? "&" : "")."\$".Key($arguments);
}
}
$result[]=array(
"Data"=>"Function $name($argument_list)",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>"{",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>1,
"Type"=>"INDENT"
);
for($part=0;$part<count($this->classes[$class]["functions"][$name]["do"]["code"]);$part++)
{
if(strcmp($this->classes[$class]["functions"][$name]["do"]["code"][$part]["Type"],"INITIALIZATION"))
$result[]=$this->classes[$class]["functions"][$name]["do"]["code"][$part];
else
$initialization_result[]=$this->classes[$class]["functions"][$name]["do"]["code"][$part];
}
$result[]=array(
"Data"=>1,
"Type"=>"OUTDENT"
);
$result[]=array(
"Data"=>"}",
"Type"=>"COMMAND"
);
$output_function++;
}
}
}
Function GenerateClass(&$compiler,&$result,&$initialization_result,$class)
{
$result=array();
$result[]=array(
"Data"=>0,
"Type"=>"RESETINDENT"
);
if(strcmp($this->classes[$class]["file"],""))
{
$result[]=array(
"Data"=>"if(!defined(\"".$this->classes[$class]["tag"]."\"))",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>"{",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>1,
"Type"=>"INDENT"
);
$result[]=array(
"Data"=>"define(\"".$this->classes[$class]["tag"]."\",1);",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>1,
"Type"=>"OUTDENT"
);
}
$result[]=array(
"Data"=>"",
"Type"=>"COMMAND"
);
if(IsSet($this->classes[$class]["comment"])
|| IsSet($this->classes[$class]["copyright"]))
{
$result[]=array(
"Data"=>"/*",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" *",
"Type"=>"COMMAND"
);
if(IsSet($this->classes[$class]["copyright"]))
{
$this->GenerateComment($this->classes[$class]["copyright"],&$result);
if(IsSet($this->classes[$class]["comment"]))
{
$result[]=array(
"Data"=>" *",
"Type"=>"COMMAND"
);
}
}
if(IsSet($this->classes[$class]["comment"]))
$this->GenerateComment($this->classes[$class]["comment"],&$result);
$result[]=array(
"Data"=>" *",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>" */",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>"",
"Type"=>"COMMAND"
);
}
$result[]=array(
"Data"=>"class ".$this->classes[$class]["name"].(IsSet($this->classes[$class]["parent"]) ? " extends ".$this->classes[$this->classes[$class]["parent"]]["name"] : ""),
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>"{",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>1,
"Type"=>"INDENT"
);
$this->GenerateVariables(&$result,$class,1);
$this->GenerateVariables(&$result,$class,0);
if(count($this->classes[$class]["variables"])
&& count($this->classes[$class]["functions"]))
{
$result[]=array(
"Data"=>"",
"Type"=>"COMMAND"
);
}
$this->GenerateFunctions(&$compiler,&$result,$class,1);
$this->GenerateFunctions(&$compiler,&$result,$class,0);
$result[]=array(
"Data"=>1,
"Type"=>"OUTDENT"
);
$result[]=array(
"Data"=>"};",
"Type"=>"COMMAND"
);
$result[]=array(
"Data"=>"",
"Type"=>"COMMAND"
);
if(strcmp($this->classes[$class]["file"],""))
{
$result[]=array(
"Data"=>"}",
"Type"=>"COMMAND"
);
}
$result[]=array(
"Data"=>0,
"Type"=>"RESTOREINDENT"
);
return(1);
}
Function GetSubclassArgument(&$compiler,$file,$path,&$values)
{
if(IsSet($value["subclass"]))
{
$compiler->SetElementError($file,$path,"it was specified the class object subclass argument more than once");
return(0);
}
if(!$compiler->GetValidData($file,$path,&$subclass,"it was not specified a valid class subclass argument"))
return(0);
if(!IsSet($this->subclasses[$subclass]))
{
$compiler->SetElementError($file,$path,"it was not specified a defined subclass (\"$subclass\")");
return(0);
}
$values["subclass"]=$this->subclasses[$subclass];
return(1);
}
Function GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,$allow_tags,&$tags)
{
$output=array();
$elements=$arguments_code->structure[$arguments->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$arguments->path.",$element";
$data=$arguments_code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "subclass":
if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$output))
return(0);
break;
default:
if(!$allow_tags)
{
$compiler->SetElementError($arguments->file,$element_path,$data["Tag"]." is not a supported class object scope tag");
return(0);
}
if(IsSet($tags[$data["Tag"]]))
{
$compiler->SetElementError($arguments->file,$element_path,"it was specified the class scope tag ".$data["Tag"]." more than once");
return(0);
}
$compiler->CopyEmptyContext(&$arguments,&$tags[$data["Tag"]]);
$tags[$data["Tag"]]->path=$element_path;
break;
}
}
else
{
if(!$compiler->CheckWhiteSpace($arguments->file,$data,$element_path))
return(0);
}
}
$class=(IsSet($output["subclass"]) ? $output["subclass"] : $this->current_subclass);
return(1);
}
Function Execute(&$compiler,&$code,$function,&$context,&$arguments_code,&$arguments)
{
if(strcmp($compiler->language["name"],"PHP"))
{
$compiler->SetElementError($context->file,$context->path,$compiler->language["name"]." is not a language supported by the class class");
return(0);
}
switch($function)
{
case "load":
$load=array();
$elements=$arguments_code->structure[$arguments->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$arguments->path.",$element";
$data=$arguments_code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "subclass":
if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$load))
return(0);
break;
case "classpointer":
case "error":
if(IsSet($load[$data["Tag"]]))
{
$compiler->SetElementError($arguments->file,$element_path,"it was specified the class load ".$data["Tag"]." argument more than once");
return(0);
}
$evaluate_context=$arguments;
$evaluate_context->path=$element_path;
if(!$compiler->GetValidExpression(&$evaluate_context,"STRING","NOTRIGHT","it was not specified a valid class load ".$data["Tag"]." variable",1)
|| !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$load[$data["Tag"]],&$expression_type))
return(0);
break;
default:
$compiler->SetElementError($arguments->file,$element_path,$data["Tag"]." is not a supported class load argument");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($arguments->file,$data,$element_path))
return(0);
}
}
$subclass=(IsSet($load["subclass"]) ? $load["subclass"] : 0);
$relative_path=$compiler->RelativePath($this->classes[$subclass]["basepath"],$this->classes[$subclass]["file"]);
$context->result[]=array(
"Data"=>array(
"Name"=>$this->classes[$subclass]["file"],
"Type"=>"SUPPLIED"
),
"Type"=>"FILE"
);
$context->result[]=array(
"Data"=>"if(!defined(\"".$this->classes[0]["tag"]."\")",
"Type"=>"COMMAND"
);
$context->result[]=array(
"Data"=>"&& file_exists(\"$relative_path\"))",
"Type"=>"COMMAND"
);
$context->result[]=array(
"Data"=>"{",
"Type"=>"COMMAND"
);
$context->result[]=array(
"Data"=>1,
"Type"=>"INDENT"
);
$context->result[]=array(
"Data"=>"include(\"$relative_path\");",
"Type"=>"COMMAND"
);
if(IsSet($load["error"]))
{
$context->result[]=array(
"Data"=>$load["error"]."=\"\";",
"Type"=>"COMMAND"
);
}
$context->result[]=array(
"Data"=>1,
"Type"=>"OUTDENT"
);
$context->result[]=array(
"Data"=>"}",
"Type"=>"COMMAND"
);
if(IsSet($load["error"]))
{
$context->result[]=array(
"Data"=>"else",
"Type"=>"COMMAND"
);
$context->result[]=array(
"Data"=>1,
"Type"=>"INDENT"
);
$context->result[]=array(
"Data"=>$load["error"]."=\"could not access the class code file \\\"$relative_path\\\"\";",
"Type"=>"COMMAND"
);
$context->result[]=array(
"Data"=>1,
"Type"=>"OUTDENT"
);
}
if(IsSet($load["classpointer"]))
{
$context->result[]=array(
"Data"=>$load["classpointer"]."=\"".$this->classes[$subclass]["name"]."\";",
"Type"=>"COMMAND"
);
}
break;
case "new":
$new=array();
$elements=$arguments_code->structure[$arguments->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$arguments->path.",$element";
$data=$arguments_code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "subclass":
if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$new))
return(0);
break;
case "classpointer":
if(IsSet($new[$data["Tag"]]))
{
$compiler->SetElementError($arguments->file,$element_path,"it was specified the class new ".$data["Tag"]." argument more than once");
return(0);
}
$evaluate_context=$arguments;
$evaluate_context->path=$element_path;
if(!$compiler->GetValidExpression(&$evaluate_context,"STRING","NOTLEFT","it was not specified a valid class new ".$data["Tag"]." argument",1)
|| !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$new[$data["Tag"]],&$expression_type))
return(0);
break;
default:
$compiler->SetElementError($arguments->file,$element_path,$data["Tag"]." is not a supported class new argument");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($arguments->file,$data,$element_path))
return(0);
}
}
$subclass=(IsSet($new["subclass"]) ? $new["subclass"] : 0);
$context->result[]=array(
"Data"=>array(
"Object"=>$this->object_name,
"Context"=>$this->classes[$subclass]["name"]
),
"Type"=>"INITIALIZATION"
);
if(IsSet($new["classpointer"]))
$class_name=$new["classpointer"];
else
{
$class_name=$this->classes[$subclass]["name"];
for($class=$subclass;;$class=$this->classes[$class]["parent"])
{
$this->classes[$class]["staticload"]=1;
if(!$class)
break;
}
}
$context->result[]=array(
"Data"=>array(
"Value"=>"new $class_name",
"Type"=>"OBJECT",
"Class"=>$this->classes[$subclass]["name"],
"Side"=>"RIGHT"
),
"Type"=>"EXPRESSION"
);
break;
case "instancecall":
case "call":
$call=array();
if(!$this->Call(&$compiler,&$arguments_code,&$arguments,&$call,$function)
|| !$this->Call(&$compiler,&$code,&$context,&$call,$function))
return(0);
if((strcmp($function,"instancecall")
&& !IsSet($call[$argument="object"]))
|| !IsSet($call[$argument="function"]))
{
$compiler->SetElementError($context->file,$context->path,"it was not defined the class $function $argument argument");
return(0);
}
$argument_list="";
$class=$subclass=(IsSet($call["subclass"]) ? $call["subclass"] : $this->current_subclass);
$this->InheritedFunctionClass(&$class,$call["function"]);
if(IsSet($this->classes[$class]["functions"][$call["function"]]["Arguments"]))
{
$arguments=$this->classes[$class]["functions"][$call["function"]]["Arguments"];
for(Reset($arguments),$argument=0;$argument<count($arguments);Next($arguments),$argument++)
{
$argument_name=Key($arguments);
if(IsSet($call["arguments"][$argument_name]))
{
$argument_context=$call["arguments"][$argument_name];
$evaluate_context=$context;
$evaluate_context->file=$argument_context["file"];
$evaluate_context->path=$argument_context["path"];
$reference=IsSet($argument_context["reference"]);
if(!$compiler->GetValidExpression(&$evaluate_context,$argument_context["type"],$reference ? "BOTH" : "NOTLEFT","it was not specified a valid class function $function argument ".$argument_context["type"]." ".($reference ? "reference" : "value")." expression",0)
|| !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$argument_value,&$expression_type))
return(0);
}
else
{
if(!IsSet($arguments[$argument_name]["defaultvalue"]))
{
$compiler->SetElementError($context->file,$context->path,"it was not specified the class $function ".$argument_name." argument");
return(0);
}
$argument_value=$arguments[$argument_name]["converteddefaultvalue"];
}
if($argument>0)
$argument_list.=",";
$argument_list.=$argument_value;
}
}
$statement=(strcmp($function,"instancecall") ? $call["object"] : "\$this")."->".$call["function"]."($argument_list)";
if(strcmp($this->classes[$class]["functions"][$call["function"]]["type"],"VOID"))
{
$context->result[]=array(
"Data"=>array(
"Value"=>$statement,
"Type"=>$this->classes[$class]["functions"][$call["function"]]["type"],
"Side"=>"RIGHT"
),
"Type"=>"EXPRESSION"
);
}
else
{
$context->result[]=array(
"Data"=>$statement.";",
"Type"=>"COMMAND"
);
}
break;
case "return":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags))
return(0);
if(!strcmp($this->classes[$class]["return_type"],""))
{
$compiler->SetElementError($context->file,$context->path,"the return function is being from called outside a class function");
return(0);
}
if(!strcmp($this->classes[$class]["return_type"],"VOID"))
{
$compiler->SetElementError($context->file,$context->path,"it was attempted to return a value from a function with return type set to VOID");
return(0);
}
$evaluate_context=$context;
if(!$compiler->GetValidExpression(&$evaluate_context,$this->classes[$class]["return_type"],"NOTLEFT","it was not specified a valid class function return ".$this->classes[$class]["return_type"]." expression",1)
|| !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$return_value,&$expression_type))
return(0);
$context->result[]=array(
"Data"=>"return $return_value;",
"Type"=>"COMMAND"
);
$this->classes[$class]["return_value_set"]=1;
break;
case "instancevariable":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags))
return(0);
if(!strcmp($this->classes[$class]["return_type"],""))
{
$compiler->SetElementError($context->file,$context->path,"the instance variable is being accessed from outside a class function");
return(0);
}
if(!$compiler->GetValidName($context->file,$context->path,&$name,"it was not specified a valid class variable name"))
return(0);
if(!$this->InheritedVariableClass(&$class,$name))
{
$compiler->SetElementError($context->file,$context->path,"it was not specified a defined class variable name (\"$name\")");
return(0);
}
$context->result[]=array(
"Data"=>array(
"Value"=>"\$"."this->$name",
"Type"=>$this->classes[$class]["variables"][$name]["type"],
"Side"=>"BOTH"
),
"Type"=>"EXPRESSION"
);
break;
case "objectvariable":
$object_variable=array();
$elements=$arguments_code->structure[$arguments->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$arguments->path.",$element";
$data=$arguments_code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "subclass":
if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$object_variable))
return(0);
break;
case "object":
if(IsSet($object_variable["object"]))
{
$compiler->SetElementError($arguments->file,$element_path,"it was specified the class object variable object argument more than once");
return(0);
}
$evaluate_context=$arguments;
$evaluate_context->path=$element_path;
if(!$compiler->GetValidExpression(&$evaluate_context,"OBJECT","NOTLEFT","it was not specified a valid class object variable object expression",1)
|| !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$object_variable["object"],&$expression_type))
return(0);
break;
default:
$compiler->SetElementError($arguments->file,$element_path,$data["Tag"]." is not a supported class object variable argument");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($arguments->file,$data,$element_path))
return(0);
}
}
if(!IsSet($object_variable["object"]))
{
$compiler->SetElementError($arguments->file,$arguments->path,"it was not specified the class object variable object argument");
return(0);
}
if(!$compiler->GetValidName($context->file,$context->path,&$name,"it was not specified a valid class variable name"))
return(0);
$subclass=(IsSet($object_variable["subclass"]) ? $object_variable["subclass"] : 0);
if(!$this->InheritedVariableClass(&$subclass,$name))
{
$compiler->SetElementError($context->file,$context->path,"it was not specified a defined class variable name (\"$name\")");
return(0);
}
if(IsSet($this->classes[$subclass]["variables"][$name]["private"]))
{
$compiler->SetElementError($context->file,$context->path,"it was attempted to access an object private variable (\"$name\") from outside the class scope");
return(0);
}
$context->result[]=array(
"Data"=>array(
"Value"=>$object_variable["object"]."->$name",
"Type"=>$this->classes[$subclass]["variables"][$name]["type"],
"Side"=>"BOTH"
),
"Type"=>"EXPRESSION"
);
break;
case "functionargument":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags))
return(0);
if(!strcmp($this->classes[$class]["function_name"],""))
{
$compiler->SetElementError($context->file,$context->path,"the function argument function is being from called outside a class function");
return(0);
}
if(!$compiler->GetValidName($context->file,$context->path,&$name,"it was not specified a valid class function argument name"))
return(0);
if(!IsSet($this->classes[$class]["functions"][$this->classes[$class]["function_name"]]["Arguments"][$name]))
{
$compiler->SetElementError($context->file,$context->path,"it was specified an unknown class function argument (\"$name\")");
return(0);
}
$argument=$this->classes[$class]["functions"][$this->classes[$class]["function_name"]]["Arguments"][$name];
$context->result[]=array(
"Data"=>array(
"Value"=>"\$".$name,
"Type"=>$argument["type"],
"Side"=>"BOTH"
),
"Type"=>"EXPRESSION"
);
break;
case "output":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags))
return(0);
if(!strcmp($this->classes[$class]["file"],""))
{
$compiler->SetElementError($context->file,$context->path,"it was not specified the class output file");
return(0);
}
if(!$this->GenerateClass(&$compiler,&$result,&$initialization_result,$class)
|| !$compiler->GenerateOutput(&$context,&$result,&$output,"",0)
|| !$compiler->CreateContextOutputDirectory(dirname($this->classes[$class]["file"]),&$context,"it was not possible to create the directory for the class output file \"".dirname($this->classes[$class]["file"])."\""))
return(0);
if(!($output_file=@fopen($this->classes[$class]["file"],"w")))
{
$compiler->SetElementError($context->file,$context->path,"it was not possible to open the class output file \"".$this->classes[$class]["file"]."\"");
return(0);
}
$written=fwrite($output_file,$output);
$closed=fclose($output_file);
if($written!=strlen($output)
|| !$closed)
{
$compiler->SetElementError($context->file,$context->path,"it was not possible to write to the class output file");
return(0);
}
$context->result[]=array(
"Data"=>array(
"Name"=>$this->classes[$class]["file"],
"Type"=>"GENERATED"
),
"Type"=>"FILE"
);
break;
case "subclass":
if(!$this->SetupClass(&$compiler,&$arguments_code,&$arguments))
return(0);
break;
case "getproperty":
case "definedproperty":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags))
return(0);
if(!$compiler->GetValidName($context->file,$context->path,&$property,"it was not specified a valid class property name"))
return(0);
switch($property)
{
case "file":
case "basepath":
case "tag":
case "comment":
case "copyright":
case "title":
case "author":
case "authoraddress":
if(!strcmp($function,"getproperty"))
{
if(!IsSet($this->classes[$class][$property]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested a property value (\"$property\") not defined for the specified class");
return(0);
}
$context->result[]=array(
"Data"=>$this->classes[$class][$property],
"Type"=>"DATA"
);
}
else
{
$context->result[]=array(
"Data"=>(IsSet($this->classes[$class][$property]) ? "1" : "0"),
"Type"=>"DATA"
);
}
break;
default:
$compiler->SetElementError($context->file,$context->path,"\"$property\" is not a supported class property");
return(0);
}
break;
case "definetypes":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags))
return(0);
$elements=$code->structure[$context->path]["Elements"];
for($element=0;$element<$elements;$element++)
{
$element_path=$context->path.",$element";
$data=$code->structure[$element_path];
if(GetType($data)=="array")
{
switch($data["Tag"])
{
case "VOID":
case "STRING":
case "INTEGER":
case "FLOAT":
case "BOOLEAN":
case "OBJECT":
case "ARRAY":
case "HASH":
if(IsSet($this->classes[$class]["types"][$data["Tag"]]))
{
$compiler->SetElementError($context->file,$element_path,"it was defined the class data type \"".$data["Tag"]."\" more than once");
return(0);
}
if(!$compiler->GetValidData($context->file,$element_path,&$this->classes[$class]["types"][$data["Tag"]],"it was not specified a valid class data type option"))
return(0);
break;
default:
$compiler->SetElementError($context->file,$element_path,"it was not defined a valid class data type");
return(0);
}
}
else
{
if(!$compiler->CheckWhiteSpace($context->file,$data,$element_path))
return(0);
}
}
break;
case "forallfunctions":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags))
return(0);
if(IsSet($tags["idiom"])
&& !$compiler->GetValidName($tags["idiom"]->file,$tags["idiom"]->path,&$idiom,"it was not specified a valid class documentation idiom tag"))
return(0);
$private=$public=1;
if(IsSet($tags["private"]))
{
if(!$compiler->GetValidData($tags["private"]->file,$tags["private"]->path,&$value,"it was not specified a valid class function public value"))
return(0);
switch($value)
{
case "1":
case "":
$private=1;
break;
case "0":
$private=0;
break;
default:
$compiler->SetElementError($tags["private"]->file,$tags["private"]->path,"it was not specified a valid class function private value");
return(0);
}
}
if(IsSet($tags["public"]))
{
if(!$compiler->GetValidData($tags["public"]->file,$tags["public"]->path,&$value,"it was not specified a valid class function public value"))
return(0);
switch($value)
{
case "1":
case "":
$public=1;
break;
case "0":
$public=0;
break;
default:
$compiler->SetElementError($tags["public"]->file,$tags["public"]->path,"it was not specified a valid class function public value");
return(0);
}
}
$functions=array(
"functionname",
"functiontype",
"functiontypename",
"functionistype",
"forallarguments"
);
if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level))
return(0);
$current_class=$this->current_class;
$current_function=$this->current_function;
for($class_function=0,Reset($this->classes[$class]["functions"]);$class_function<count($this->classes[$class]["functions"]);Next($this->classes[$class]["functions"]),$class_function++)
{
$this->current_class=$class;
$this->current_function=Key($this->classes[$class]["functions"]);
if(($public
&& !IsSet($this->classes[$class]["functions"][$this->current_function]["private"]))
|| ($private
&& IsSet($this->classes[$class]["functions"][$this->current_function]["private"])))
{
if(!$compiler->GetOutputData($context->file,$context->path,&$context->result,"it was not defined valid action for the class functions",1))
{
$this->current_class=$current_class;
$this->current_function=$current_function;
return(0);
}
}
}
$this->current_class=$current_class;
$this->current_function=$current_function;
if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level))
return(0);
break;
case "forallvariables":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags))
return(0);
if(IsSet($tags["idiom"])
&& !$compiler->GetValidName($tags["idiom"]->file,$tags["idiom"]->path,&$idiom,"it was not specified a valid class documentation idiom tag"))
return(0);
$private=$public=1;
if(IsSet($tags["private"]))
{
if(!$compiler->GetValidData($tags["private"]->file,$tags["private"]->path,&$value,"it was not specified a valid class variable public value"))
return(0);
switch($value)
{
case "1":
case "":
$private=1;
break;
case "0":
$private=0;
break;
default:
$compiler->SetElementError($tags["private"]->file,$tags["private"]->path,"it was not specified a valid class variable private value");
return(0);
}
}
if(IsSet($tags["public"]))
{
if(!$compiler->GetValidData($tags["public"]->file,$tags["public"]->path,&$value,"it was not specified a valid class variable public value"))
return(0);
switch($value)
{
case "1":
case "":
$public=1;
break;
case "0":
$public=0;
break;
default:
$compiler->SetElementError($tags["public"]->file,$tags["public"]->path,"it was not specified a valid class variable public value");
return(0);
}
}
$functions=array(
"variablename",
"variabletype",
"variabletypename",
"definedvariabledefaultvalue",
"variabledefaultvalue",
"variableconvertedvalue"
);
if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level))
return(0);
$current_class=$this->current_class;
$current_variable=$this->current_variable;
for($class_variable=0,Reset($this->classes[$class]["variables"]);$class_variable<count($this->classes[$class]["variables"]);Next($this->classes[$class]["variables"]),$class_variable++)
{
$this->current_class=$class;
$this->current_variable=Key($this->classes[$class]["variables"]);
if(($public
&& !IsSet($this->classes[$class]["variables"][$this->current_variable]["private"]))
|| ($private
&& IsSet($this->classes[$class]["variables"][$this->current_variable]["private"])))
{
if(!$compiler->GetOutputData($context->file,$context->path,&$context->result,"it was not defined valid action for the class variables",1))
{
$this->current_class=$current_class;
$this->current_variable=$current_variable;
return(0);
}
}
}
$this->current_class=$current_class;
$this->current_variable=$current_variable;
if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level))
return(0);
break;
case "forallarguments":
if(!strcmp($this->current_function,""))
{
$compiler->SetElementError($context->file,$context->path,"it was requested to iterate over function arguments outside a function definition scope");
return(0);
}
if(IsSet($tags["idiom"])
&& !$compiler->GetValidName($tags["idiom"]->file,$tags["idiom"]->path,&$idiom,"it was not specified a valid class documentation idiom tag"))
return(0);
$current_class=$this->current_class;
$current_function=$this->current_function;
$current_argument=$this->current_argument;
if(!IsSet($this->classes[$current_class]["functions"][$current_function]["Arguments"]))
break;
$functions=array(
"argumentname",
"argumenttype",
"argumenttypename",
"referenceargument",
"lastargument"
);
if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level))
return(0);
for($this->current_argument_number=0,Reset($this->classes[$current_class]["functions"][$current_function]["Arguments"]);$this->current_argument_number<count($this->classes[$current_class]["functions"][$current_function]["Arguments"]);Next($this->classes[$current_class]["functions"][$current_function]["Arguments"]),$this->current_argument_number++)
{
$this->current_class=$current_class;
$this->current_function=$current_function;
$this->current_argument=Key($this->classes[$current_class]["functions"][$current_function]["Arguments"]);
if(!$compiler->GetOutputData($context->file,$context->path,&$context->result,"it was not defined valid action for the class function arguments",0))
{
$this->current_class=$current_class;
$this->current_function=$current_function;
$this->current_argument=$current_argument;
return(0);
}
}
$this->current_class=$current_class;
$this->current_function=$current_function;
$this->current_argument=$current_argument;
if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level))
return(0);
break;
case "getdocumentation":
case "defineddocumentation":
if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags))
return(0);
if(!IsSet($tags["idiom"]))
{
$compiler->SetElementError($context->file,$context->path,"it was not specified the class documentation idiom");
return(0);
}
if(!$compiler->GetValidName($tags["idiom"]->file,$tags["idiom"]->path,&$idiom,"it was not specified a valid class documentation idiom tag"))
return(0);
if(!$compiler->GetValidName($context->file,$context->path,&$tag,"it was not specified a valid class documentation tag"))
return(0);
if(strcmp($this->current_argument,""))
{
if(strcmp($function,"defineddocumentation"))
{
if(!IsSet($this->classes[$class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["documentation"][$idiom][$tag]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the value of a documentation tag (\"$tag\") that is not defined for the specified class function argument");
return(0);
}
if(!$compiler->GetOutputData($this->classes[$class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["documentation"][$idiom][$tag]->file,$this->classes[$class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["documentation"][$idiom][$tag]->path,&$context->result,"it was not defined valid class function argument documentation tag",0))
return(0);
}
else
{
$context->result[]=array(
"Data"=>(IsSet($this->classes[$class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["documentation"][$idiom][$tag]) ? "1" : "0"),
"Type"=>"DATA"
);
}
}
else
{
if(strcmp($this->current_function,""))
{
if(strcmp($function,"defineddocumentation"))
{
if(!IsSet($this->classes[$class]["functions"][$this->current_function]["documentation"][$idiom][$tag]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the value of a documentation tag (\"$tag\") that is not defined for the specified class function");
return(0);
}
if(!$compiler->GetOutputData($this->classes[$class]["functions"][$this->current_function]["documentation"][$idiom][$tag]->file,$this->classes[$class]["functions"][$this->current_function]["documentation"][$idiom][$tag]->path,&$context->result,"it was not defined valid class function argument documentation tag",0))
return(0);
}
else
{
$context->result[]=array(
"Data"=>(IsSet($this->classes[$class]["functions"][$this->current_function]["documentation"][$idiom][$tag]) ? "1" : "0"),
"Type"=>"DATA"
);
}
}
else
{
if(strcmp($this->current_variable,""))
{
if(strcmp($function,"defineddocumentation"))
{
if(!IsSet($this->classes[$class]["variables"][$this->current_variable]["documentation"][$idiom][$tag]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the value of a documentation tag (\"$tag\") that is not defined for the specified class variable");
return(0);
}
if(!$compiler->GetOutputData($this->classes[$class]["variables"][$this->current_variable]["documentation"][$idiom][$tag]->file,$this->classes[$class]["variables"][$this->current_variable]["documentation"][$idiom][$tag]->path,&$context->result,"it was not defined valid class variable argument documentation tag",0))
return(0);
}
else
{
$context->result[]=array(
"Data"=>(IsSet($this->classes[$class]["variables"][$this->current_variable]["documentation"][$idiom][$tag]) ? "1" : "0"),
"Type"=>"DATA"
);
}
}
else
{
if(strcmp($function,"defineddocumentation"))
{
if(!IsSet($this->classes[$class]["documentation"][$idiom][$tag]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the value of a documentation tag (\"$tag\") that is not defined for the specified class");
return(0);
}
if(!$compiler->GetOutputData($this->classes[$class]["documentation"][$idiom][$tag]->file,$this->classes[$class]["documentation"][$idiom][$tag]->path,&$context->result,"it was not defined valid class documentation tag",0))
return(0);
}
else
{
$context->result[]=array(
"Data"=>(IsSet($this->classes[$class]["documentation"][$idiom][$tag]) ? "1" : "0"),
"Type"=>"DATA"
);
}
}
}
}
break;
case "functionname":
case "functiontype":
case "functiontypename":
case "functionistype":
if(!strcmp($this->current_function,""))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the $function of function outside a function definition scope");
return(0);
}
switch($function)
{
case "functionname":
$value=$this->current_function;
break;
case "functiontype":
$value=$this->classes[$this->current_class]["functions"][$this->current_function]["type"];
break;
case "functiontypename":
$value=$this->classes[$this->current_class]["functions"][$this->current_function]["type"];
if(IsSet($this->classes[$this->current_class]["types"][$value]))
$value=$this->classes[$this->current_class]["types"][$value];
break;
case "functionistype":
if(!$compiler->GetValidData($context->file,$context->path,&$type,"it was not specified a valid class function return type"))
return(0);
switch($type)
{
case "VOID":
case "STRING":
case "INTEGER":
case "FLOAT":
case "BOOLEAN":
case "OBJECT":
case "ARRAY":
case "HASH":
break;
default:
$compiler->SetElementError($context->file,$context->path,"it was not defined a valid class function return type");
return(0);
}
$value=(strcmp($type,$this->classes[$this->current_class]["functions"][$this->current_function]["type"]) ? "0" : "1");
break;
}
$context->result[]=array(
"Data"=>$value,
"Type"=>"DATA"
);
break;
case "argumentname":
case "argumenttype":
case "argumenttypename":
case "referenceargument":
case "lastargument":
if(!strcmp($this->current_argument,""))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the $function of function argument outside a function argument definition scope");
return(0);
}
switch($function)
{
case "argumentname":
$value=$this->current_argument;
break;
case "argumenttype":
$value=$this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["type"];
break;
case "argumenttypename":
$value=$this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["type"];
if(IsSet($this->classes[$this->current_class]["types"][$value]))
$value=$this->classes[$this->current_class]["types"][$value];
break;
case "referenceargument":
$value=(IsSet($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["reference"]) ? "1" : "0");
break;
case "lastargument":
$value=($this->current_argument_number+1==count($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"]) ? "1" : "0");
break;
}
$context->result[]=array(
"Data"=>$value,
"Type"=>"DATA"
);
break;
case "variablename":
case "variabletype":
case "variabletypename":
case "definedvariabledefaultvalue":
case "variabledefaultvalue":
case "variableconvertedvalue":
if(!strcmp($this->current_variable,""))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the $function of variable outside a variable definition scope");
return(0);
}
switch($function)
{
case "variablename":
$value=$this->current_variable;
break;
case "variabletype":
$value=$this->classes[$this->current_class]["variables"][$this->current_variable]["type"];
break;
case "variabletypename":
$value=$this->classes[$this->current_class]["variables"][$this->current_variable]["type"];
if(IsSet($this->classes[$this->current_class]["types"][$value]))
$value=$this->classes[$this->current_class]["types"][$value];
break;
case "definedvariabledefaultvalue":
$value=(IsSet($this->classes[$this->current_class]["variables"][$this->current_variable]["value"]) ? "1" : "0");
break;
case "variabledefaultvalue":
if(!IsSet($this->classes[$this->current_class]["variables"][$this->current_variable]["value"]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the value of a class variable (".$this->current_variable.") that does not have a defined default value");
return(0);
}
$value=$this->classes[$this->current_class]["variables"][$this->current_variable]["value"];
break;
case "variableconvertedvalue":
if(!IsSet($this->classes[$this->current_class]["variables"][$this->current_variable]["convertedvalue"]))
{
$compiler->SetElementError($context->file,$context->path,"it was requested the convertedvalue of a class variable (".$this->current_variable.") that does not have a defined default value");
return(0);
}
$value=$this->classes[$this->current_class]["variables"][$this->current_variable]["convertedvalue"];
break;
}
$context->result[]=array(
"Data"=>$value,
"Type"=>"DATA"
);
break;
default:
$compiler->SetElementError($context->file,$context->path,$function." is not a supported class object function");
return(0);
}
return(1);
}
Function Initialization(&$compiler,&$context,$object_context)
{
if(strcmp($compiler->language["name"],"PHP"))
{
$compiler->SetElementError($context->file,$context->path,$compiler->language["name"]." is not a language supported by the class class");
return(0);
}
$class=$this->subclasses[$object_context];
for($parent=$class;$parent!=0;)
{
$parent=$this->classes[$parent]["parent"];
$context->result[]=array(
"Data"=>array(
"Object"=>$this->object_name,
"Context"=>$this->classes[$parent]["name"]
),
"Type"=>"INITIALIZATION"
);
}
if(strcmp($this->classes[$class]["file"],""))
{
for(Reset($this->classes[$class]["functions"]),$function=0;$function<count($this->classes[$class]["functions"]);$function++,Next($this->classes[$class]["functions"]))
{
$name=Key($this->classes[$class]["functions"]);
if(!$this->GenerateFunction(&$compiler,$class,$name))
return(0);
for($part=0;$part<count($this->classes[$class]["functions"][$name]["do"]["code"]);$part++)
{
switch($this->classes[$class]["functions"][$name]["do"]["code"][$part]["Type"])
{
case "INITIALIZATION":
case "FILE":
$context->result[]=$this->classes[$class]["functions"][$name]["do"]["code"][$part];
break;
}
}
}
$relative_path=$compiler->RelativePath($this->classes[$class]["basepath"],$this->classes[$class]["file"]);
$context->result[]=array(
"Data"=>array(
"Name"=>$this->classes[$class]["file"],
"Type"=>"SUPPLIED"
),
"Type"=>"FILE"
);
if($this->classes[$class]["staticload"])
{
$context->result[]=array(
"Data"=>"require(\"$relative_path\");",
"Type"=>"COMMAND"
);
}
}
else
{
if(!$this->GenerateClass(&$compiler,&$result,&$context->result,$class))
return(0);
for($part=0;$part<count($result);$part++)
$context->result[]=$result[$part];
}
return(1);
}
};
}
?>