--- metal/metal_class.php 2001/12/08 04:24:32 1.74 +++ metal/metal_class.php 2004/09/14 20:04:46 1.107 @@ -1,4 +1,4 @@ -classes[$class]["parent"])) + $this->OutputDependencies($context,$this->classes[$class]["parent"]); + if(IsSet($this->dependencies[$class])) + { + for($dependency=0;$dependencydependencies[$class]);$dependency++) + { + $context->result[]=array( + "Data"=>array( + "Name"=>$this->dependencies[$class][$dependency], + "Type"=>"DEPENDENCY" + ), + "Type"=>"FILE" + ); + } + } + } + + Function GetDocumentation(&$scope,&$compiler,&$code,&$attributes,$element_path,$default_scope) { Unset($idiom); $documentation=array(); @@ -40,7 +61,7 @@ class metal_class_class extends metal_ba $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")) + 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])) { @@ -54,7 +75,7 @@ class metal_class_class extends metal_ba $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"]]); + $compiler->CopyEmptyContext($attributes,$documentation[$data["Tag"]]); $documentation[$data["Tag"]]->path=$documentation_element_path; break; } @@ -67,21 +88,28 @@ class metal_class_class extends metal_ba } if(!IsSet($idiom)) { - $compiler->SetElementError($attributes->file,$element_path,"it was not defined the class documentation idiom"); - return(0); + if(IsSet($default_scope["documentation"])) + { + Reset($default_scope["documentation"]); + $idiom=Key($default_scope["documentation"]); + } + else + { + $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) + Function SetupClass(&$compiler,&$code,&$attributes,$file) { $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; @@ -97,7 +125,7 @@ class metal_class_class extends metal_ba switch($data["Tag"]) { case "parent": - if(!$compiler->GetValidName($attributes->file,$element_path,&$parent_name,"it was not specified a valid class parent name argument")) + 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"])) { @@ -127,7 +155,7 @@ class metal_class_class extends metal_ba $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")) + 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])) { @@ -143,6 +171,16 @@ class metal_class_class extends metal_ba $this->classes[$index]["name"]=$class_name; $this->subclasses[$class_name]=$index; break; + case "package": + if(IsSet($this->classes[$index]["package"])) + { + $compiler->SetElementError($attributes->file,$element_path,"it was defined the class package more than once"); + return(0); + } + if(!$compiler->GetValidData($attributes->file,$element_path,$class_package,"it was not specified a valid class package argument")) + return(0); + $this->classes[$index]["package"]=$class_package; + break; case "function": Unset($name); $function=array(); @@ -161,7 +199,7 @@ class metal_class_class extends metal_ba $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")) + 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])) { @@ -184,6 +222,8 @@ class metal_class_class extends metal_ba $function["Arguments"]=$this->classes[$class_parent]["functions"][$name]["Arguments"]; if(IsSet($this->classes[$class_parent]["functions"][$name]["protected"])) $function["protected"]=$this->classes[$class_parent]["functions"][$name]["protected"]; + if(IsSet($this->classes[$class_parent]["functions"][$name]["package"])) + $function["package"]=$this->classes[$class_parent]["functions"][$name]["package"]; break; } if(!IsSet($this->classes[$class_parent]["parent"])) @@ -208,9 +248,9 @@ class metal_class_class extends metal_ba $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")) + 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"]) + switch($compiler->strtok($function["type"],":")) { case "VOID": case "STRING": @@ -226,24 +266,31 @@ class metal_class_class extends metal_ba return(0); } break; + case "package": + if(!IsSet($this->classes[$index]["package"])) + { + $compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function package access status before specifying the class package"); + return(0); + } case "protected": if(!IsSet($name)) { - $compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function protected status before specifying its name"); + $compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function ".$data["Tag"]." access 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 protected status of a inherited subclass function"); + $compiler->SetElementError($attributes->file,$function_element_path,"it was attempted to redefine the class ".$data["Tag"]." access status of a inherited subclass function"); return(0); } - if(IsSet($function["protected"])) + if(IsSet($function["package"]) + || IsSet($function["protected"])) { - $compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function protected status more than once"); + $compiler->SetElementError($attributes->file,$function_element_path,"it was defined the class function access status more than once"); return(0); } - $function["protected"]=1; + $function[$data["Tag"]]=1; break; case "argument": if(!IsSet($name)) @@ -274,7 +321,7 @@ class metal_class_class extends metal_ba $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")) + 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])) { @@ -288,9 +335,9 @@ class metal_class_class extends metal_ba $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")) + 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"]) + switch($compiler->strtok($argument["type"],":")) { case "STRING": case "INTEGER": @@ -326,8 +373,8 @@ class metal_class_class extends metal_ba $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"])) + 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 "in": @@ -352,7 +399,7 @@ class metal_class_class extends metal_ba $argument["parameter"]=$data["Tag"]; break; case "documentation": - if(!$this->GetDocumentation(&$argument,&$compiler,&$code,&$attributes,$argument_element_path)) + if(!$this->GetDocumentation($argument,$compiler,$code,$attributes,$argument_element_path,$this->classes[$index])) return(0); break; default: @@ -376,8 +423,54 @@ class metal_class_class extends metal_ba $compiler->SetElementError($attributes->file,$function_element_path,"it was not defined the class function argument type"); return(0); } + if(GetType($colon=strpos($type=$argument["type"],":"))=="integer") + { + $class=substr($argument["type"],$colon); + $type=substr($argument["type"],0,$colon); + } + else + $class=""; if(!IsSet($argument["parameter"])) - $argument["parameter"]="in"; + { + switch($type) + { + case "ARRAY": + case "HASH": + case "OBJECT": + $argument["parameter"]="inout"; + break; + default: + $argument["parameter"]="in"; + break; + } + } + switch($argument["parameter"]) + { + case "out": + case "inout": + switch($type) + { + case "ARRAY": + case "HASH": + case "OBJECT": + $buffer=""; + break; + default: + $buffer="BUFFER"; + } + $argument["type"]=$type.$buffer.$class; + break; + default: + switch($type) + { + case "ARRAY": + case "HASH": + case "OBJECT": + $compiler->SetElementError($attributes->file,$function_element_path,"arguments of type \"$type\" may only be \"out\" or \"inout\" parameters"); + return(0); + } + break; + } $function["Arguments"][$argument_name]=$argument; break; case "do": @@ -393,7 +486,7 @@ class metal_class_class extends metal_ba $this->classes[$index]["functions"][$name]=$function; break; case "documentation": - if(!$this->GetDocumentation(&$function,&$compiler,&$code,&$attributes,$function_element_path)) + if(!$this->GetDocumentation($function,$compiler,$code,$attributes,$function_element_path,$this->classes[$index])) return(0); break; default: @@ -446,7 +539,7 @@ class metal_class_class extends metal_ba $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")) + 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])) { @@ -459,6 +552,8 @@ class metal_class_class extends metal_ba $variable["type"]=$this->classes[$parent]["variables"][$name]["type"]; if(IsSet($this->classes[$parent]["variables"][$name]["protected"])) $variable["protected"]=$this->classes[$parent]["variables"][$name]["protected"]; + if(IsSet($this->classes[$parent]["variables"][$name]["package"])) + $variable["protected"]=$this->classes[$parent]["variables"][$name]["package"]; } break; case "type": @@ -468,7 +563,7 @@ class metal_class_class extends metal_ba return(0); } $class=$parent; - if($this->InheritedVariableClass(&$class,$name)) + 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); @@ -478,9 +573,9 @@ class metal_class_class extends metal_ba $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")) + 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"]) + switch($compiler->strtok($variable["type"],":")) { case "STRING": case "INTEGER": @@ -495,28 +590,49 @@ class metal_class_class extends metal_ba return(0); } break; + case "package": case "protected": if(!IsSet($name)) { - $compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable protected status before specifying its name"); + $compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable ".$data["Tag"]." access status before specifying its name"); return(0); } $class=$parent; - if($this->InheritedVariableClass(&$class,$name)) + if($this->InheritedVariableClass($class,$name)) { - $compiler->SetElementError($attributes->file,$variable_element_path,"it was attempted to redefine the protected status of a inherited subclass variable"); + $compiler->SetElementError($attributes->file,$variable_element_path,"it was attempted to redefine the ".$data["Tag"]." access status of a inherited subclass variable"); return(0); } - if(IsSet($variable["protected"])) + if(IsSet($variable["package"]) + || IsSet($variable["protected"])) { - $compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable protected status more than once"); + $compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable access status more than once"); return(0); } - $variable["protected"]=1; + $variable[$data["Tag"]]=1; + break; + case "notnull": + if(!IsSet($name)) + { + $compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable notnull 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 notnull status of a inherited subclass variable"); + return(0); + } + if(IsSet($variable["notnull"])) + { + $compiler->SetElementError($attributes->file,$variable_element_path,"it was defined the class variable notnull status more than once"); + return(0); + } + $variable["notnull"]=1; break; case "value": $class=$parent; - if($this->InheritedVariableClass(&$class,$name)) + if($this->InheritedVariableClass($class,$name)) $type=$this->classes[$class]["variables"][$name]["type"]; else { @@ -532,12 +648,12 @@ class metal_class_class extends metal_ba $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"])) + 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)) + if(!$this->GetDocumentation($variable,$compiler,$code,$attributes,$variable_element_path,$this->classes[$index])) return(0); break; default: @@ -557,12 +673,15 @@ class metal_class_class extends metal_ba return(0); } $class=$parent; - if(!$this->InheritedVariableClass(&$class,$name) + if(!$this->InheritedVariableClass($class,$name) && !IsSet($variable["type"])) { $compiler->SetElementError($attributes->file,$element_path,"it was not defined the class variable type"); return(0); } + if(IsSet($variable["notnull"]) + && !IsSet($variable["value"])) + return($compiler->SetElementError($attributes->file,$element_path,"it was not defined the default value of a notnull class variable")); $this->classes[$index]["variables"][$name]=$variable; break; case "abstract": @@ -576,11 +695,13 @@ class metal_class_class extends metal_ba 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")) + if(!$compiler->GetValidData($attributes->file,$element_path,$this->classes[$index][$data["Tag"]],"it was not specified a valid class ".$data["Tag"]." property")) return(0); + if(strlen($this->classes[$index][$data["Tag"]])==0) + return($compiler->SetElementError($attributes->file,$element_path,"it was specified an empty class ".$data["Tag"]." property")); break; case "documentation": - if(!$this->GetDocumentation(&$this->classes[$index],&$compiler,&$code,&$attributes,$element_path)) + if(!$this->GetDocumentation($this->classes[$index],$compiler,$code,$attributes,$element_path,$this->classes[$index])) return(0); break; default: @@ -613,12 +734,15 @@ class metal_class_class extends metal_ba && !IsSet($this->classes[$parent]["abstract"])) { $compiler->SetElementError($attributes->file,$attributes->path,"it was defined the abstract attribute for a subclass of a class that is not abstract"); - return(0); + return(0); } $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"])); + if(strlen($file)) + { + $include_path=$compiler->GetIncludePath($file); + $this->dependencies[$index][]=$include_path.$file; + } return(1); } @@ -641,7 +765,17 @@ class metal_class_class extends metal_ba } $class_attributes=$attributes; $class_attributes->path=$element_path; - if(!$this->SetupClass(&$compiler,&$code,&$class_attributes)) + if(!$this->SetupClass($compiler,$code,$class_attributes,"")) + return(0); + break; + case "definition": + if(!$compiler->GetValidData($attributes->file,$element_path,$file,"it was not specified a valid class definition file")) + return(0); + if(!$compiler->ParseDefinitionFile($file)) + return(0); + $compiler->CreateFileContext($class_attributes,$file); + $compiler->GetParser($parser,$file); + if(!$this->SetupClass($compiler,$parser,$class_attributes,$file)) return(0); break; default: @@ -662,6 +796,12 @@ class metal_class_class extends metal_ba { if(!IsSet($this->classes[$class]["functions"][$name]["do"]["code"])) { + if(IsSet($this->generate_function[$class][$name])) + { + $compiler->SetElementError($this->classes[$class]["functions"][$name]["do"]["file"],$this->classes[$class]["functions"][$name]["do"]["path"],"Generate function is being called recursively for class function \"$name\""); + return(0); + } + $this->generate_function[$class][$name]=1; $this->classes[$class]["functions"][$name]["do"]["code"]=array(); $function_name=$this->classes[$class]["function_name"]; $return_type=$this->classes[$class]["return_type"]; @@ -669,27 +809,45 @@ class metal_class_class extends metal_ba $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"]; + $compiler->CreateFileContext($action_context,$this->classes[$class]["functions"][$name]["do"]["file"]); $action_context->path=$this->classes[$class]["functions"][$name]["do"]["path"]; - $action_context->result=array(); $functions=array( + "instance", "instancevariable", + "instancevariableisnotnull", "instancecall", "functionargument", - "return" + "setinstancevariablenull", + "return", + "classpackage" ); - if(!$compiler->AddContextFunctions(&$action_context,$this->object_name,&$functions,&$level) - || !$compiler->StartScope(&$action_context,&$scope,"method")) + if(!$compiler->AddContextFunctions($action_context,$this->object_name,$functions,$level) + || !$compiler->StartScope($action_context,$scope,"method")) return(0); + if(IsSet($this->classes[$class]["functions"][$name]["Arguments"])) + { + $arguments=$this->classes[$class]["functions"][$name]["Arguments"]; + for(Reset($arguments),$argument=0;$argument$argument_name, + "Type"=>$arguments[$argument_name]["type"], + "Argument"=>1 + ); + if(!$compiler->DeclareVariable($action_context,$variable)) + return(0); + } + } $current_subclass=$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) - || !$compiler->GetScopeVariables(&$context,$scope,&$this->classes[$class]["functions"][$name]["variables"])) + 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) + || !$compiler->GetScopeVariables($context,$scope,$this->classes[$class]["functions"][$name]["variables"]) + || !$compiler->GetScopeExceptions($context,$scope,$this->classes[$class]["functions"][$name]["exceptions"])) return(0); $this->current_subclass=$current_subclass; - $success=$compiler->EndScope(&$action_context,$scope); - if(!$compiler->RemoveContextFunctions(&$action_context,$this->object_name,$level) + $success=$compiler->EndScope($action_context,$scope); + if(!$compiler->RemoveContextFunctions($action_context,$this->object_name,$level) || !$success) return(0); if(strcmp($this->classes[$class]["functions"][$name]["type"],"VOID") @@ -701,6 +859,7 @@ class metal_class_class extends metal_ba $this->classes[$class]["function_name"]=$function_name; $this->classes[$class]["return_type"]=$return_type; $this->classes[$class]["return_value_set"]=$return_value_set; + Unset($this->generate_function[$class][$name]); } return(1); } @@ -745,7 +904,7 @@ class metal_class_class extends metal_ba $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)) + if(!$this->GetSubclassArgument($compiler,$context->file,$element_path,$call)) return(0); $subclass=$call["subclass"]; break; @@ -756,10 +915,10 @@ class metal_class_class extends metal_ba $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")) + 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"])) + 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); @@ -771,6 +930,12 @@ class metal_class_class extends metal_ba $compiler->SetElementError($context->file,$element_path,"it was not defined the function to call before specifying the $function arguments"); 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); + } 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"); @@ -808,20 +973,35 @@ class metal_class_class extends metal_ba } break; case "object": + case "package": if(strcmp($function,"instancecall")) { - $argument=$data["Tag"]; - if(IsSet($call[$argument])) + if($data["Tag"]=="package") { - $compiler->SetElementError($context->file,$element_path,"it was specified the class $function $argument argument more than once"); - return(0); + if(IsSet($call["package"])) + { + $compiler->SetElementError($context->file,$element_path,"it was specified the class call package argument more than once"); + return(0); + } + if(!$compiler->GetValidData($context->file,$element_path,$call["package"],"it was not specified a valid class $function function argument")) + return(0); + break; + } + else + { + $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); + } + $compiler->CopyEmptyContext($context,$evaluate_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; } - $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"); @@ -844,7 +1024,7 @@ class metal_class_class extends metal_ba $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")) + if(!$compiler->GetValidData($file,$path,$subclass,"it was not specified a valid class subclass argument")) return(0); if(!IsSet($this->subclasses[$subclass])) { @@ -868,7 +1048,7 @@ class metal_class_class extends metal_ba switch($data["Tag"]) { case "subclass": - if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$output)) + if(!$this->GetSubclassArgument($compiler,$arguments->file,$element_path,$output)) return(0); break; default: @@ -882,7 +1062,7 @@ class metal_class_class extends metal_ba $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"]]); + $compiler->CopyEmptyContext($arguments,$tags[$data["Tag"]]); $tags[$data["Tag"]]->path=$element_path; break; } @@ -897,49 +1077,111 @@ class metal_class_class extends metal_ba return(1); } - Function IterateVariables(&$compiler,&$context,$class,&$variables,$protected,$public,$inherited) + Function IterateVariables(&$compiler,&$context,$class,&$variables,$package,$protected,$public,$inherited) { + if(IsSet($this->classes[$class]["parent"])) + { + $parent=$this->classes[$class]["parent"]; + switch($inherited) + { + case "0": + $inherit=0; + $current=1; + break; + case "1": + $inherit=1; + $current=0; + break; + case "all": + $inherit=1; + $current=1; + break; + default: + $compiler->SetElementError($context->file,$context->path,"$inherited is not a supported inherited variable type"); + return(0); + } + } + else + { + $inherit=0; + $current=1; + } for($class_variable=0,Reset($this->classes[$class]["variables"]);$class_variableclasses[$class]["variables"]);Next($this->classes[$class]["variables"]),$class_variable++) { $this->current_class=$class; $this->current_variable=Key($this->classes[$class]["variables"]); if(!IsSet($variables[$this->current_variable]) && (($public + && !IsSet($this->classes[$class]["variables"][$this->current_variable]["package"]) && !IsSet($this->classes[$class]["variables"][$this->current_variable]["protected"])) + || ($package + && IsSet($this->classes[$class]["variables"][$this->current_variable]["package"])) || ($protected && IsSet($this->classes[$class]["variables"][$this->current_variable]["protected"])))) { - if(!$compiler->GetOutputData($context->file,$context->path,&$context->result,"it was not defined valid action for the class variables",1)) + if($current + && !$compiler->GetOutputData($context->file,$context->path,$context->result,"it was not defined valid action for the class variables",1)) return(0); $variables[$this->current_variable]=$class; } } - if($inherited - && IsSet($this->classes[$class]["parent"])) - return($this->IterateVariables($compiler,$context,$this->classes[$class]["parent"],&$variables,$protected,$public,$inherited)); + if($inherit) + return($this->IterateVariables($compiler,$context,$parent,$variables,$package,$protected,$public,$inherited)); return(1); } - Function IterateFunctions(&$compiler,&$context,$class,&$functions,$protected,$public,$inherited) + Function IterateFunctions(&$compiler,&$context,$class,&$functions,$package,$protected,$public,$inherited) { + if(IsSet($this->classes[$class]["parent"])) + { + $parent=$this->classes[$class]["parent"]; + switch($inherited) + { + case "0": + $inherit=0; + $current=1; + break; + case "1": + $inherit=1; + $current=0; + break; + case "all": + $inherit=1; + $current=1; + break; + default: + $compiler->SetElementError($context->file,$context->path,"$inherited is not a supported inherited function type"); + return(0); + } + if($inherit) + return($this->IterateFunctions($compiler,$context,$parent,$functions,$package,$protected,$public,$inherited)); + } + else + { + $inherit=0; + $current=1; + } for($class_function=0,Reset($this->classes[$class]["functions"]);$class_functionclasses[$class]["functions"]);Next($this->classes[$class]["functions"]),$class_function++) { $this->current_class=$class; $this->current_function=Key($this->classes[$class]["functions"]); if(!IsSet($functions[$this->current_function]) && (($public + && !IsSet($this->classes[$class]["functions"][$this->current_function]["package"]) && !IsSet($this->classes[$class]["functions"][$this->current_function]["protected"])) + || ($package + && IsSet($this->classes[$class]["functions"][$this->current_function]["package"])) || ($protected && IsSet($this->classes[$class]["functions"][$this->current_function]["protected"])))) { - if(!$compiler->GetOutputData($context->file,$context->path,&$context->result,"it was not defined valid action for the class functions",1)) + if($current + && !$compiler->GetOutputData($context->file,$context->path,$context->result,"it was not defined valid action for the class functions",1)) return(0); $functions[$this->current_function]=$class; } } - if($inherited - && IsSet($this->classes[$class]["parent"])) - return($this->IterateFunctions($compiler,$context,$this->classes[$class]["parent"],&$functions,$protected,$public,$inherited)); + if($inherit) + return($this->IterateFunctions($compiler,$context,$parent,$functions,$package,$protected,$public,$inherited)); return(1); } @@ -956,6 +1198,38 @@ class metal_class_class extends metal_ba case "instancevariable": case "instancecall": case "call": + case "getproperty": + case "definedproperty": + case "getdocumentation": + case "defineddocumentation": + case "examplecode": + case "new": + case "objectvariable": + case "forallvariables": + case "forallfunctions": + case "variablename": + case "variabletype": + case "variabletypename": + case "definedvariabledefaultvalue": + case "variabledefaultvalue": + case "variableconvertedvalue": + case "functionname": + case "functiontype": + case "functiontypename": + case "functionistype": + case "functionhasarguments": + case "forallarguments": + case "argumentname": + case "argumenttype": + case "argumenttypename": + case "argumentparameter": + case "inargument": + case "outargument": + case "inoutargument": + case "lastargument": + case "definedargumentdefaultvalue": + case "argumentdefaultvalue": + case "argumentconvertedvalue": break; default: $compiler->SetElementError($context->file,$context->path,"$function function of the class class is not implemented for the language ".$compiler->language["name"]); @@ -982,7 +1256,7 @@ class metal_class_class extends metal_ba switch($data["Tag"]) { case "subclass": - if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$load)) + if(!$this->GetSubclassArgument($compiler,$arguments->file,$element_path,$load)) return(0); break; case "classpointer": @@ -994,8 +1268,8 @@ class metal_class_class extends metal_ba } $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)) + 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: @@ -1015,6 +1289,11 @@ class metal_class_class extends metal_ba $compiler->SetElementError($context->file,$context->path,"an abstract class can not be loaded"); return(0); } + if(!IsSet($this->classes[$subclass]["file"]) + || strlen($this->classes[$subclass]["file"])==0) + return($compiler->SetElementError($context->file,$context->path,"it was not specified the class output file")); + if(!IsSet($this->classes[$subclass]["tag"])) + $this->classes[$subclass]["tag"]="CLASS_".strtoupper(ereg_replace("[^A-Za-z0-9]","_",$this->classes[$subclass]["file"])); $relative_path=$compiler->RelativePath($this->classes[$subclass]["basepath"],$this->classes[$subclass]["file"]); $context->result[]=array( "Data"=>array( @@ -1024,7 +1303,7 @@ class metal_class_class extends metal_ba "Type"=>"FILE" ); $context->result[]=array( - "Data"=>"if(!defined(\"".$this->classes[0]["tag"]."\")", + "Data"=>"if(!defined(\"".$this->classes[$subclass]["tag"]."\")", "Type"=>"COMMAND" ); $context->result[]=array( @@ -1084,9 +1363,10 @@ class metal_class_class extends metal_ba "Type"=>"COMMAND" ); } + $this->OutputDependencies($context,$subclass); break; case "new": - $new=array(); + $message=array(); $elements=$arguments_code->structure[$arguments->path]["Elements"]; for($element=0;$element<$elements;$element++) { @@ -1097,19 +1377,19 @@ class metal_class_class extends metal_ba switch($data["Tag"]) { case "subclass": - if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$new)) + if(!$this->GetSubclassArgument($compiler,$arguments->file,$element_path,$message)) return(0); break; case "classpointer": - if(IsSet($new[$data["Tag"]])) + if(IsSet($message[$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)) + 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,$message[$data["Tag"]],$expression_type)) return(0); break; default: @@ -1123,46 +1403,23 @@ class metal_class_class extends metal_ba return(0); } } - $subclass=(IsSet($new["subclass"]) ? $new["subclass"] : 0); + if(!IsSet($message["subclass"])) + $message["subclass"]=0; + $subclass=$message["subclass"]; if(IsSet($this->classes[$subclass]["abstract"])) { $compiler->SetElementError($context->file,$context->path,"an abstract class can not be instanciated"); return(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" - ); + if(!$this->language_bindings->Execute($compiler,$context,$this,$function,$message)) + return(0); + $this->OutputDependencies($context,$subclass); break; case "instancecall": case "call": $message=array(); - if(!$this->Call(&$compiler,&$arguments_code,&$arguments,&$message,$function) - || !$this->Call(&$compiler,&$code,&$context,&$message,$function)) + if(!$this->Call($compiler,$arguments_code,$arguments,$message,$function) + || !$this->Call($compiler,$code,$context,$message,$function)) return(0); if((strcmp($function,"instancecall") && !IsSet($message[$argument="object"])) @@ -1178,7 +1435,22 @@ class metal_class_class extends metal_ba $compiler->SetElementError($context->file,$context->path,"an abstract class can not be called"); return(0); } - $this->InheritedFunctionClass(&$message["class"],$message["function"]); + $this->InheritedFunctionClass($message["class"],$message["function"]); + if($function=="call") + { + if(IsSet($this->classes[$message["class"]]["functions"][$message["function"]]["protected"])) + { + $compiler->SetElementError($context->file,$context->path,"it was attempted to call an object protected function (\"".$message["function"]."\") from outside the class scope"); + return(0); + } + if(IsSet($this->classes[$message["class"]]["functions"][$message["function"]]["package"])) + { + if(!IsSet($message["package"])) + return($compiler->SetElementError($context->file,$context->path,"it was attempted to call an object package function (\"".$message["function"]."\") from outside the class scope")); + if(strcmp($this->classes[$message["class"]]["package"],$message["package"])) + return($compiler->SetElementError($context->file,$context->path,"it was attempted to call an object package function (\"".$message["function"]."\") from a different package")); + } + } $message["argumentlist"]=array(); if(IsSet($this->classes[$message["class"]]["functions"][$message["function"]]["Arguments"])) { @@ -1189,7 +1461,7 @@ class metal_class_class extends metal_ba if(IsSet($message["arguments"][$argument_name])) { $argument_context=$message["arguments"][$argument_name]; - $evaluate_context=$context; + $compiler->CopyEmptyContext($context,$evaluate_context); $evaluate_context->file=$argument_context["file"]; $evaluate_context->path=$argument_context["path"]; switch($this->classes[$message["class"]]["functions"][$message["function"]]["Arguments"][$argument_name]["parameter"]) @@ -1207,8 +1479,8 @@ class metal_class_class extends metal_ba $error="it was not specified a valid class function $function argument ".$argument_context["type"]." input/output expression"; break; } - if(!$compiler->GetValidExpression(&$evaluate_context,"ANY",$side,$error,0) - || !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$argument_value,&$expression_type)) + if(!$compiler->GetValidExpression($evaluate_context,"ANY",$side,$error,0) + || !$compiler->GetExpressionValue($context,$evaluate_context->result,$argument_value,$expression_type)) return(0); if($expression_type=="UNDEFINED" && $side=="NOTRIGHT") @@ -1217,15 +1489,16 @@ class metal_class_class extends metal_ba "DeclarationFile"=>$evaluate_context->file, "DeclarationPath"=>$evaluate_context->path.",0" ); - if(!$compiler->QueryVariable(&$context,&$variable)) + if(!$compiler->QueryVariable($context,$variable)) return(0); if($variable["Declared"]) { $variable["Type"]=$argument_context["type"]; - if(!$compiler->DeclareVariable(&$context,&$variable)) + $variable["Initialized"]=0; + if(!$compiler->DeclareVariable($context,$variable)) return(0); - if(!$compiler->GetValidExpression(&$evaluate_context,$argument_context["type"],$side,$error,0) - || !$compiler->GetExpressionValue(&$context,&$evaluate_context->result,&$argument_value,&$expression_type)) + if(!$compiler->GetValidExpression($evaluate_context,$argument_context["type"],$side,$error,0) + || !$compiler->GetExpressionValue($context,$evaluate_context->result,$argument_value,$expression_type)) return(0); } } @@ -1247,54 +1520,106 @@ class metal_class_class extends metal_ba $message["argumentlist"][]=$argument_value; } } - if(!$this->language_bindings->Execute(&$compiler,&$context,&$this,$function,&$message)) + if(!$this->language_bindings->Execute($compiler,$context,$this,$function,$message)) return(0); + $this->OutputDependencies($context,$subclass); break; case "return": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags)) + 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); } + $message=array(); 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); + if($code->structure[$context->path]["Elements"]) + { + $compiler->SetElementError($context->file,$context->path,"it was attempted to return a value from a function with return type set to VOID"); + return(0); + } + $message["value"]=""; } - $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); - $message=array( - "value"=>$return_value - ); - if(!$this->language_bindings->Execute(&$compiler,&$context,&$this,"return",&$message)) + else + { + $compiler->CopyEmptyContext($context,$evaluate_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,$message["value"],$expression_type)) + return(0); + } + if(!$this->language_bindings->Execute($compiler,$context,$this,"return",$message)) return(0); $this->classes[$class]["return_value_set"]=1; + $this->OutputDependencies($context,$class); + break; + case "instance": + $message=array(); + if(!$this->GetClassScope($compiler,$arguments_code,$arguments,$message["class"],0,$tags)) + return(0); + $class=$message["class"]; + if(!strcmp($this->classes[$message["class"]]["return_type"],"")) + { + $compiler->SetElementError($context->file,$context->path,"the instance variable is being accessed from outside a class function"); + return(0); + } + if(!$this->language_bindings->Execute($compiler,$context,$this,"instance",$message)) + return(0); + $this->OutputDependencies($context,$class); break; case "instancevariable": + case "instancevariableisnotnull": + case "setinstancevariablenull": $message=array(); - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$message["class"],0,$tags)) + if(!$this->GetClassScope($compiler,$arguments_code,$arguments,$message["class"],0,$tags)) return(0); + $class=$message["class"]; if(!strcmp($this->classes[$message["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,&$message["name"],"it was not specified a valid class variable name")) + if(!$compiler->GetValidName($context->file,$context->path,$message["name"],"it was not specified a valid class variable name")) return(0); - if(!$this->InheritedVariableClass(&$message["class"],$message["name"])) + if(!$this->InheritedVariableClass($message["class"],$message["name"])) { $compiler->SetElementError($context->file,$context->path,"it was not specified a defined class variable name (\"".$message["name"]."\")"); return(0); } - if(!$this->language_bindings->Execute(&$compiler,&$context,&$this,"instancevariable",&$message)) + switch($function) + { + case "instancevariableisnotnull": + case "setinstancevariablenull": + if(IsSet($this->classes[$message["class"]]["variables"][$message["name"]]["notnull"])) + return($compiler->SetElementError($context->file,$context->path,"it was specified a class variable name (\"".$message["name"]."\") that is notnull")); + } + if(!$this->language_bindings->Execute($compiler,$context,$this,$function,$message)) + return(0); + $this->OutputDependencies($context,$class); + break; + case "classpackage": + 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 class package is being retrieved from outside a class function"); + return(0); + } + if(!IsSet($this->classes[$class]["package"])) + { + $compiler->SetElementError($context->file,$context->path,"the package name was not defined for this class"); return(0); + } + $context->result[]=array( + "Data"=>$this->classes[$class]["package"], + "Type"=>"DATA" + ); break; case "objectvariable": - $object_variable=array(); + case "objectvariableisnotnull": + case "setobjectvariablenull": + $message=array(); $elements=$arguments_code->structure[$arguments->path]["Elements"]; for($element=0;$element<$elements;$element++) { @@ -1305,19 +1630,28 @@ class metal_class_class extends metal_ba switch($data["Tag"]) { case "subclass": - if(!$this->GetSubclassArgument(&$compiler,$arguments->file,$element_path,&$object_variable)) + if(!$this->GetSubclassArgument($compiler,$arguments->file,$element_path,$message)) return(0); break; case "object": - if(IsSet($object_variable["object"])) + if(IsSet($message["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)) + 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,$message["object"],$expression_type)) + return(0); + break; + case "package": + if(IsSet($message["package"])) + { + $compiler->SetElementError($arguments->file,$element_path,"it was defined the class object variable package argument more than once"); + return(0); + } + if(!$compiler->GetValidData($arguments->file,$element_path,$message["package"],"it was not specified a valid class object variable package argument")) return(0); break; default: @@ -1331,20 +1665,38 @@ class metal_class_class extends metal_ba return(0); } } - if(!IsSet($object_variable["object"])) + if(IsSet($message["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); } - 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); + else + { + $values=array(); + $required_types=array( + "object"=>"OBJECT", + "variable"=>"NAME" + ); + $optional_types=array( + ); + if(!IsSet($message["package"])) + $optional_values["package"]="DATA"; + if(!$compiler->GetOptionalArgumentValues($context,$values,$required_types,$optional_types,"class",$function,1)) + return(0); + $message["object"]=$values["object"]; + $name=$values["variable"]; + if(IsSet($values["package"])) + $message["package"]=$values["package"]; + } + if(!IsSet($message["subclass"])) + $message["subclass"]=0; + $subclass=$message["subclass"]; if(IsSet($this->classes[$subclass]["abstract"])) { $compiler->SetElementError($context->file,$context->path,"abstract class variables can not be accessed"); return(0); } - if(!$this->InheritedVariableClass(&$subclass,$name)) + if(!$this->InheritedVariableClass($subclass,$name)) { $compiler->SetElementError($context->file,$context->path,"it was not specified a defined class variable name (\"$name\")"); return(0); @@ -1354,55 +1706,59 @@ class metal_class_class extends metal_ba $compiler->SetElementError($context->file,$context->path,"it was attempted to access an object protected 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" - ); + if(IsSet($this->classes[$subclass]["variables"][$name]["package"])) + { + if(!IsSet($message["package"])) + return($compiler->SetElementError($context->file,$context->path,"it was attempted to access an object package variable (\"".$name."\") from outside the class scope")); + if(strcmp($this->classes[$subclass]["package"],$message["package"])) + return($compiler->SetElementError($context->file,$context->path,"it was attempted to access an object package variable (\"".$name."\") from a different package")); + } + $message["subclass"]=$subclass; + $message["name"]=$name; + if(!$this->language_bindings->Execute($compiler,$context,$this,$function,$message)) + return(0); + $this->OutputDependencies($context,$subclass); break; case "functionargument": $message=array(); - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$message["class"],0,$tags)) + if(!$this->GetClassScope($compiler,$arguments_code,$arguments,$message["class"],0,$tags)) return(0); + $class=$message["class"]; if(!strcmp($this->classes[$message["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,&$message["name"],"it was not specified a valid class function argument name")) + if(!$compiler->GetValidName($context->file,$context->path,$message["name"],"it was not specified a valid class function argument name")) return(0); if(!IsSet($this->classes[$message["class"]]["functions"][$this->classes[$message["class"]]["function_name"]]["Arguments"][$message["name"]])) { $compiler->SetElementError($context->file,$context->path,"it was specified an unknown class function argument (\"".$message["name"]."\")"); return(0); } - if(!$this->language_bindings->Execute(&$compiler,&$context,&$this,"functionargument",&$message)) + if(!$this->language_bindings->Execute($compiler,$context,$this,"functionargument",$message)) return(0); + $this->OutputDependencies($context,$class); break; case "output": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags)) + if(!$this->GetClassScope($compiler,$arguments_code,$arguments,$class,0,$tags)) return(0); if(IsSet($this->classes[$class]["abstract"])) { $compiler->SetElementError($context->file,$context->path,"abstract classes can not be generated"); 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(!IsSet($this->classes[$class]["file"]) + || strlen($this->classes[$class]["file"])==0) + return($compiler->SetElementError($context->file,$context->path,"it was not specified the class output file")); $message=array( "class"=>$class, "result"=>array(), "initialization"=>array() ); - if(!$this->language_bindings->Execute(&$compiler,&$context,&$this,"output",&$message) - || !$compiler->GenerateOutput(&$context,&$message["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"])."\"")) + if(!$this->language_bindings->Execute($compiler,$context,$this,"output",$message) + || !$compiler->GenerateOutput($context,$message["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"))) { @@ -1424,22 +1780,57 @@ class metal_class_class extends metal_ba ), "Type"=>"FILE" ); + $this->OutputDependencies($context,$class); break; case "subclass": - if(!$this->SetupClass(&$compiler,&$arguments_code,&$arguments)) + $types=array( + ); + $optional_types=array( + "class"=>"CONTEXT", + "definition"=>"DATA", + ); + $values=array(); + if(!$compiler->GetOptionalArgumentValues($arguments,$values,$types,$optional_types,"class",$function,0) + || !$compiler->GetOptionalArgumentValues($context,$values,$types,$optional_types,"class",$function,1)) return(0); + if(IsSet($values["class"])) + { + if(IsSet($values["definition"])) + { + $compiler->SetElementError($context->file,$context->path,"it was specified both an internal and an external subclass definition"); + return(0); + } + $compiler->CopyEmptyContext($values["class"],$class_attributes); + $compiler->GetParser($parser,$class_attributes->file); + if(!$this->SetupClass($compiler,$parser,$class_attributes,"")) + return(0); + } + elseif(IsSet($values["definition"])) + { + if(!$compiler->ParseDefinitionFile($values["definition"])) + return(0); + $compiler->CreateFileContext($class_attributes,$values["definition"]); + $compiler->GetParser($parser,$values["definition"]); + if(!$this->SetupClass($compiler,$parser,$class_attributes,$values["definition"])) + return(0); + } + else + { + $compiler->SetElementError($context->file,$context->path,"it was not specified the subclass definition"); + return(0); + } break; case "getproperty": case "definedproperty": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags)) + 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")) + 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 "package": case "version": case "copyright": case "title": @@ -1482,65 +1873,35 @@ class metal_class_class extends metal_ba return(0); } break; - case "definetypes": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,0,$tags)) + case "forallfunctions": + if(!$this->GetClassScope($compiler,$arguments_code,$arguments,$class,1,$tags)) return(0); - $elements=$code->structure[$context->path]["Elements"]; - for($element=0;$element<$elements;$element++) + 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); + $package=$protected=$public=1; + $inherited=0; + if(IsSet($tags["package"])) { - $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,&$type,"it was not specified a valid class data type option")) - return(0); - $type_name=$data["Tag"]; - $this->classes[$class]["types"][$type_name]=$type; - $parent=$class; - while(IsSet($this->classes[$parent]["parent"])) - { - $parent=$this->classes[$parent]["parent"]; - $this->classes[$parent]["types"][$type_name]=$type; - } - break; - default: - $compiler->SetElementError($context->file,$element_path,"it was not defined a valid class data type"); - return(0); - } - } - else + if(!$compiler->GetValidData($tags["package"]->file,$tags["package"]->path,$value,"it was not specified a valid class function package value")) + return(0); + switch($value) { - if(!$compiler->CheckWhiteSpace($context->file,$data,$element_path)) + case "1": + case "": + $package=1; + break; + case "0": + $package=0; + break; + default: + $compiler->SetElementError($tags["package"]->file,$tags["package"]->path,"it was not specified a valid class function package value"); 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); - $protected=$public=1; - $inherited=0; if(IsSet($tags["protected"])) { - if(!$compiler->GetValidData($tags["protected"]->file,$tags["protected"]->path,&$value,"it was not specified a valid class function public value")) + if(!$compiler->GetValidData($tags["protected"]->file,$tags["protected"]->path,$value,"it was not specified a valid class function protected value")) return(0); switch($value) { @@ -1558,7 +1919,7 @@ class metal_class_class extends metal_ba } if(IsSet($tags["public"])) { - if(!$compiler->GetValidData($tags["public"]->file,$tags["public"]->path,&$value,"it was not specified a valid class function public value")) + if(!$compiler->GetValidData($tags["public"]->file,$tags["public"]->path,$value,"it was not specified a valid class function public value")) return(0); switch($value) { @@ -1576,16 +1937,19 @@ class metal_class_class extends metal_ba } if(IsSet($tags["inherited"])) { - if(!$compiler->GetValidData($tags["inherited"]->file,$tags["inherited"]->path,&$value,"it was not specified a valid class function inherited value")) + if(!$compiler->GetValidData($tags["inherited"]->file,$tags["inherited"]->path,$value,"it was not specified a valid class function inherited value")) return(0); switch($value) { case "1": case "": - $inherited=1; + $inherited="1"; break; case "0": - $inherited=0; + $inherited="0"; + break; + case "all": + $inherited="all"; break; default: $compiler->SetElementError($tags["inherited"]->file,$tags["inherited"]->path,"it was not specified a valid class function inherited value"); @@ -1600,29 +1964,48 @@ class metal_class_class extends metal_ba "functionhasarguments", "forallarguments" ); - if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level)) + if(!$compiler->AddContextFunctions($context,$this->object_name,$functions,$level)) return(0); $current_class=$this->current_class; $current_function=$this->current_function; $functions=array(); - $success=$this->IterateFunctions($compiler,$context,$class,$functions,$protected,$public,$inherited); + $success=$this->IterateFunctions($compiler,$context,$class,$functions,$package,$protected,$public,$inherited); $this->current_class=$current_class; $this->current_function=$current_function; - if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level) - || !$success) + if(!$success + || !$compiler->RemoveContextFunctions($context,$this->object_name,$level)) return(0); + $this->OutputDependencies($context,$class); break; case "forallvariables": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags)) + 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")) + && !$compiler->GetValidName($tags["idiom"]->file,$tags["idiom"]->path,$idiom,"it was not specified a valid class documentation idiom tag")) return(0); - $protected=$public=1; + $package=$protected=$public=1; $inherited=0; + if(IsSet($tags["package"])) + { + if(!$compiler->GetValidData($tags["package"]->file,$tags["package"]->path,$value,"it was not specified a valid class variable package value")) + return(0); + switch($value) + { + case "1": + case "": + $package=1; + break; + case "0": + $package=0; + break; + default: + $compiler->SetElementError($tags["package"]->file,$tags["package"]->path,"it was not specified a valid class variable package value"); + return(0); + } + } if(IsSet($tags["protected"])) { - if(!$compiler->GetValidData($tags["protected"]->file,$tags["protected"]->path,&$value,"it was not specified a valid class variable public value")) + if(!$compiler->GetValidData($tags["protected"]->file,$tags["protected"]->path,$value,"it was not specified a valid class variable protected value")) return(0); switch($value) { @@ -1640,7 +2023,7 @@ class metal_class_class extends metal_ba } if(IsSet($tags["public"])) { - if(!$compiler->GetValidData($tags["public"]->file,$tags["public"]->path,&$value,"it was not specified a valid class variable public value")) + if(!$compiler->GetValidData($tags["public"]->file,$tags["public"]->path,$value,"it was not specified a valid class variable public value")) return(0); switch($value) { @@ -1658,16 +2041,19 @@ class metal_class_class extends metal_ba } if(IsSet($tags["inherited"])) { - if(!$compiler->GetValidData($tags["inherited"]->file,$tags["inherited"]->path,&$value,"it was not specified a valid class variable inherited value")) + if(!$compiler->GetValidData($tags["inherited"]->file,$tags["inherited"]->path,$value,"it was not specified a valid class variable inherited value")) return(0); switch($value) { case "1": case "": - $inherited=1; + $inherited="1"; break; case "0": - $inherited=0; + $inherited="0"; + break; + case "all": + $inherited="all"; break; default: $compiler->SetElementError($tags["inherited"]->file,$tags["inherited"]->path,"it was not specified a valid class variable inherited value"); @@ -1682,17 +2068,18 @@ class metal_class_class extends metal_ba "variabledefaultvalue", "variableconvertedvalue" ); - if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level)) + if(!$compiler->AddContextFunctions($context,$this->object_name,$functions,$level)) return(0); $current_class=$this->current_class; $current_variable=$this->current_variable; $variables=array(); - $success=$this->IterateVariables($compiler,$context,$class,$variables,$protected,$public,$inherited); + $success=$this->IterateVariables($compiler,$context,$class,$variables,$package,$protected,$public,$inherited); $this->current_class=$current_class; $this->current_variable=$current_variable; - if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level) - || !$success) + if(!$success + || !$compiler->RemoveContextFunctions($context,$this->object_name,$level)) return(0); + $this->OutputDependencies($context,$class); break; case "forallarguments": if(!strcmp($this->current_function,"")) @@ -1701,7 +2088,7 @@ class metal_class_class extends metal_ba 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")) + && !$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; @@ -1713,16 +2100,22 @@ class metal_class_class extends metal_ba "argumenttype", "argumenttypename", "argumentparameter", - "lastargument" + "inargument", + "outargument", + "inoutargument", + "lastargument", + "definedargumentdefaultvalue", + "argumentdefaultvalue", + "argumentconvertedvalue" ); - if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level)) + 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_numberclasses[$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)) + 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; @@ -1733,17 +2126,18 @@ class metal_class_class extends metal_ba $this->current_class=$current_class; $this->current_function=$current_function; $this->current_argument=$current_argument; - if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level)) + if(!$compiler->RemoveContextFunctions($context,$this->object_name,$level)) return(0); + $this->OutputDependencies($context,$current_class); break; case "forallparentclasses": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags)) + 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")) + && !$compiler->GetValidName($tags["idiom"]->file,$tags["idiom"]->path,$idiom,"it was not specified a valid class documentation idiom tag")) return(0); $functions=array(); - if(!$compiler->AddContextFunctions(&$context,$this->object_name,&$functions,&$level)) + if(!$compiler->AddContextFunctions($context,$this->object_name,$functions,$level)) return(0); $current_class=$this->current_class; $this->current_class=$class; @@ -1751,31 +2145,32 @@ class metal_class_class extends metal_ba while(IsSet($this->classes[$this->current_class]["parent"])) { $this->current_class=$this->classes[$this->current_class]["parent"]; - if(!($success=$compiler->GetOutputData($context->file,$context->path,&$context->result,"it was not defined valid action for the class parentclasses",0))) + if(!($success=$compiler->GetOutputData($context->file,$context->path,$context->result,"it was not defined valid action for the class parentclasses",0))) break; } $this->current_class=$current_class; - if(!$compiler->RemoveContextFunctions(&$context,$this->object_name,$level) - || !$success) + if(!$success + || !$compiler->RemoveContextFunctions($context,$this->object_name,$level)) return(0); + $this->OutputDependencies($context,$class); break; case "getdocumentation": case "defineddocumentation": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags)) + 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")) + 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")) + if(!$compiler->GetValidName($context->file,$context->path,$tag,"it was not specified a valid class documentation tag")) return(0); $inherited=0; if(IsSet($tags["inherited"])) { - if(!$compiler->GetValidData($tags["inherited"]->file,$tags["inherited"]->path,&$value,"it was not specified a valid class function inherited value")) + if(!$compiler->GetValidData($tags["inherited"]->file,$tags["inherited"]->path,$value,"it was not specified a valid class function inherited value")) return(0); switch($value) { @@ -1806,7 +2201,7 @@ class metal_class_class extends metal_ba $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)) + 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 @@ -1834,7 +2229,7 @@ class metal_class_class extends metal_ba $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)) + 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 @@ -1862,7 +2257,7 @@ class metal_class_class extends metal_ba $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)) + 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 @@ -1882,7 +2277,7 @@ class metal_class_class extends metal_ba $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)) + 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 @@ -1915,14 +2310,15 @@ class metal_class_class extends metal_ba $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]; + $message=array("type"=>$this->classes[$this->current_class]["functions"][$this->current_function]["type"]); + if(!$this->language_bindings->Execute($compiler,$context,$this,"typename",$message)) + return(0); + $value=$message["name"]; break; case "functionistype": - if(!$compiler->GetValidData($context->file,$context->path,&$type,"it was not specified a valid class function return type")) + if(!$compiler->GetValidData($context->file,$context->path,$type,"it was not specified a valid class function return type")) return(0); - switch($type) + switch($compiler->strtok($type,":")) { case "VOID": case "STRING": @@ -1952,7 +2348,13 @@ class metal_class_class extends metal_ba case "argumenttype": case "argumenttypename": case "argumentparameter": + case "inargument": + case "outargument": + case "inoutargument": case "lastargument": + case "definedargumentdefaultvalue": + case "argumentdefaultvalue": + case "argumentconvertedvalue": 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"); @@ -1967,16 +2369,39 @@ class metal_class_class extends metal_ba $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]; + $message=array("type"=>$this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["type"]); + if(!$this->language_bindings->Execute($compiler,$context,$this,"typename",$message)) + return(0); + $value=$message["name"]; break; case "argumentparameter": $value=$this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["parameter"]; break; + case "inargument": + $value=($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["parameter"]=="in" ? "1" : "0"); + break; + case "outargument": + $value=($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["parameter"]=="out" ? "1" : "0"); + break; + case "inoutargument": + $value=($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["parameter"]=="inout" ? "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; + case "definedargumentdefaultvalue": + $value=(IsSet($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument]["defaultvalue"]) ? "1" : "0"); + break; + case "argumentdefaultvalue": + case "argumentconvertedvalue": + $value=(strcmp($function,"argumentconvertedvalue") ? "defaultvalue" : "converteddefaultvalue"); + if(!IsSet($this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument][$value])) + { + $compiler->SetElementError($context->file,$context->path,"it was requested the default value of an argument (".$this->current_argument.") of a function (".$this->current_function.") that does not have a defined default value"); + return(0); + } + $value=$this->classes[$this->current_class]["functions"][$this->current_function]["Arguments"][$this->current_argument][$value]; + break; } $context->result[]=array( "Data"=>$value, @@ -2003,9 +2428,10 @@ class metal_class_class extends metal_ba $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]; + $message=array("type"=>$this->classes[$this->current_class]["variables"][$this->current_variable]["type"]); + if(!$this->language_bindings->Execute($compiler,$context,$this,"typename",$message)) + return(0); + $value=$message["name"]; break; case "definedvariabledefaultvalue": $value=(IsSet($this->classes[$this->current_class]["variables"][$this->current_variable]["value"]) ? "1" : "0"); @@ -2033,55 +2459,38 @@ class metal_class_class extends metal_ba ); break; case "examplecode": - if(!$this->GetClassScope(&$compiler,&$arguments_code,&$arguments,&$class,1,$tags)) + $message=array(); + if(!$this->GetClassScope($compiler,$arguments_code,$arguments,$class,1,$tags)) return(0); $result=array(); - if(!$compiler->GetOutputData($context->file,$context->path,&$result,"invalid example code",1)) + if(!$compiler->StartScope($context,$scope,"global") + || !$compiler->GetOutputData($context->file,$context->path,$message["result"],"invalid example code",1) + || !$compiler->GetScopeVariables($context,$scope,$message["variables"]) + || !$compiler->GetScopeExceptions($context,$scope,$message["exceptions"]) + || !$compiler->EndScope($context,$scope)) return(0); $initialization=1; if(IsSet($tags["initialization"])) { - if(!$compiler->GetValidData($tags["initialization"]->file,$tags["initialization"]->path,&$value,"it was not specified a valid class example code initialization value")) + if(!$compiler->GetValidData($tags["initialization"]->file,$tags["initialization"]->path,$value,"it was not specified a valid class example code initialization value")) return(0); switch($value) { case "1": case "": - $initialization=1; + $message["initialization"]=1; break; case "0": - $initialization=0; + $message["initialization"]=0; break; default: $compiler->SetElementError($tags["initialization"]->file,$tags["initialization"]->path,"it was not specified a valid class example code initialization value"); return(0); } } - if($initialization) - { - if(!$compiler->GenerateOutput(&$context,&$result,&$output,"",0)) - return(0); - } - else - { - for($stripped=array(),$part=0;$partGenerateOutput(&$context,&$stripped,&$output,"",0)) - return(0); - } - $context->result[]=array( - "Data"=>$output, - "Type"=>"DATA" - ); + if(!$this->language_bindings->Execute($compiler,$context,$this,$function,$message)) + return(0); + $this->OutputDependencies($context,$class); break; default: $compiler->SetElementError($context->file,$context->path,$function." is not a supported class object function"); @@ -2101,7 +2510,7 @@ class metal_class_class extends metal_ba if(IsSet($this->classes[$class]["abstract"])) { $compiler->SetElementError($context->file,$context->path,"abstract class functions arguments can not be accessed"); - return(0); + return(0); } for($parent=$class;$parent!=0 && !IsSet($this->classes[$parent=$this->classes[$parent]["parent"]]["abstract"]);) { @@ -2113,12 +2522,15 @@ class metal_class_class extends metal_ba "Type"=>"INITIALIZATION" ); } + if(!IsSet($this->classes[$class]["file"]) + || strlen($this->classes[$class]["file"])==0) + return($compiler->SetElementError($context->file,$context->path,"it was not specified the class output file")); if(strcmp($this->classes[$class]["file"],"")) { for(Reset($this->classes[$class]["functions"]),$function=0;$functionclasses[$class]["functions"]);$function++,Next($this->classes[$class]["functions"])) { $name=Key($this->classes[$class]["functions"]); - if(!$this->GenerateFunction(&$compiler,$class,$name)) + if(!$this->GenerateFunction($compiler,$class,$name)) return(0); for($part=0;$partclasses[$class]["functions"][$name]["do"]["code"]);$part++) { @@ -2131,7 +2543,7 @@ class metal_class_class extends metal_ba } } } - $relative_path=$compiler->RelativePath($this->classes[$class]["basepath"],$this->classes[$class]["file"]); + $relative_path=(IsSet($this->classes[$class]["basepath"]) ? $compiler->RelativePath($this->classes[$class]["basepath"],$this->classes[$class]["file"]) : $this->classes[$class]["file"]); $context->result[]=array( "Data"=>array( "Name"=>$this->classes[$class]["file"], @@ -2154,16 +2566,17 @@ class metal_class_class extends metal_ba "result"=>array(), "initialization"=>array() ); - if(!$this->language_bindings->Execute(&$compiler,&$context,&$this,"output",&$message)) + if(!$this->language_bindings->Execute($compiler,$context,$this,"output",$message)) return(0); for($part=0;$partresult[]=$message["initialization"][$part]; for($part=0;$partresult[]=$message["result"][$part]; } + $this->OutputDependencies($context,$class); return(1); } }; - + } ?> \ No newline at end of file