o_arg.requireNodeType(Node.TYPE_QSYMBOL|Node.TYPE_LAZY);
if(o_arg.isQSymbol()){
//
// forme : ... 'symbole {...})
//
ASymbol e_symbole = o_arg.getSymbol();
Node e_body = startAt.getSubNode(++o_rel, Node.TYPE_LAZY);
startAt.isGoodArgsCnt(o_rel+1); // Vérifie la forme
Node e_function = Node.createInlineFunction(e_body);
if (e_final && !e_symbole.isImmutable())
throw new InterpreterException(StdErrors.Immutable_symbol_required);
Heap.defv(e_symbole, e_function.letFinal(e_symbole.isImmutable()));
return null;
}
else{
//
// forme : ... {...})
//
startAt.isGoodArgsCnt(o_rel+1);
Node e_body = o_arg;
Node e_function = Node.createInlineFunction(e_body).letFinal(e_final);
return e_function;
}
}
else if(e_override){
/**
* override
*/
//
// forme : ... 'symbole ...
// et : ... function ...
//
o_arg.requireNodeType(Node.TYPE_QSYMBOL|Node.TYPE_FUNCTION);
ASymbol e_symbole=null;
Node e_body=null;
Node e_super=null;
if(o_arg.isQSymbol()){
e_symbole = o_arg.getSymbol();
e_super = Heap.getv(e_symbole);
e_super.requireAccessType(Node.ACCESSVTYPE_MUTABLE_WRITELOCK);
e_super.requireNodeType(Node.TYPE_FUNCTION);
}
else{
e_super = o_arg;
e_super.requireAccessType(Node.ACCESSVTYPE_MUTABLE_WRITELOCK);
}
//
// forme : ... [{...}] ...
//
if(startAt.testSubNode(++o_rel, Node.TYPE_LAZY)){
e_body=startAt.getSubNode(o_rel, Node.TYPE_LAZY);
}
else{
o_rel--; // Attention!!! il faut revenir en arrière...
e_body=((Function) e_super.getExternal()).getBodyFx();
}
//
// Rechercher la forme [with lazy/scope] et/ou [from lazy/scope]
//
Node e_with=null;
Node e_yield=null;
while(startAt.size()>o_rel+1){
o_arg=startAt.getSubNode(++o_rel, Node.TYPE_PCODE);
if(o_arg.isPCode(PCoder.PC_WITH))
if(e_with!=null)
throw new InterpreterException(StdErrors.extend(StdErrors.Duplicate_parameters,o_arg.toString()));
else{
e_with=startAt.getSubNode(++o_rel, Node.TYPE_LAZY|Node.TYPE_SCOPE);
if(e_with.isLazy())
e_with=Node.createScope(e_with);
}
else if(o_arg.isPCode(PCoder.PC_YIELD))
if(e_yield!=null)
throw new InterpreterException(StdErrors.extend(StdErrors.Duplicate_parameters,o_arg.toString()));
else{
e_yield=startAt.getSubNode(++o_rel, Node.TYPE_LAZY|Node.TYPE_SCOPE);
if(e_yield.isLazy())
e_yield=Node.createScope(e_yield);
}
}
//
// On a tout ce qu'il faut...
//
startAt.isGoodArgsCnt(o_rel+1); // Vérifie la forme
Node e_function = Node.createOverridedFunction(e_body,e_yield,e_with,e_super);
if (e_symbole == null)
return e_function.letFinal(e_final);
else {
e_function.derefTo(e_super);
return null;
}
}
else if(e_wrapper){
/**
* wrapper
*/
//
// forme : ... ['symbole] ...
//
o_arg.requireNodeType(Node.TYPE_QSYMBOL|Node.TYPE_PCODE);
ASymbol e_symbole=null;
if(o_arg.isQSymbol()){
e_symbole = o_arg.getSymbol();
o_arg=startAt.getSubNode(++o_rel, Node.TYPE_PCODE);
}
//
// Rechercher la forme [with lazy/scope] et/ou [from lazy/scope]
//
// Attention, dans ce cas, o_arg contient déjà le premier PCode with ou yield.
// --------------------------------------------------------------------------
// La boucle est donc différente ici que dans les autres cas...
//
// De plus, il est obligatoire de stipuler au moins un des deux scopes.
// -----------
//
Node e_with=null;
Node e_yield=null;
do{
// on ne cherche o_arg que s'il est null
if(o_arg==null)
o_arg=startAt.getSubNode(++o_rel, Node.TYPE_PCODE);
if(o_arg.isPCode(PCoder.PC_WITH))
if(e_with!=null)
throw new InterpreterException(StdErrors.extend(StdErrors.Duplicate_parameters,o_arg.toString()));
else{
e_with=startAt.getSubNode(++o_rel, Node.TYPE_LAZY|Node.TYPE_SCOPE);
if(e_with.isLazy())
e_with=Node.createScope(e_with);
}
else if(o_arg.isPCode(PCoder.PC_YIELD))
if(e_yield!=null)
throw new InterpreterException(StdErrors.extend(StdErrors.Duplicate_parameters,o_arg.toString()));
else{
e_yield=startAt.getSubNode(++o_rel, Node.TYPE_LAZY|Node.TYPE_SCOPE);
if(e_yield.isLazy())
e_yield=Node.createScope(e_yield);
}
// on met o_arg=null pour la suite...
o_arg=null;
}while(startAt.size()>o_rel+1);
//
// On a tout ce qu'il faut...
//
startAt.isGoodArgsCnt(o_rel+1); // Vérifie la forme
Node e_function = Node.createFunction(null,e_yield,e_with); // on crée une fonction wrapper (sans corps)
if(e_symbole!=null){
if (e_final && !e_symbole.isImmutable())
throw new InterpreterException(StdErrors.Immutable_symbol_required);
Heap.defv(e_symbole, e_function.letFinal(e_symbole.isImmutable()));
return null;
}
else
return e_function.letFinal(e_final);
}
else{
/**
* classique
*/
//
// forme : ... 'symbole {...} ...
// et : ... {...} ...
//
o_arg.requireNodeType(Node.TYPE_QSYMBOL|Node.TYPE_LAZY);
ASymbol e_symbole=null;
if(o_arg.isQSymbol()){
e_symbole = o_arg.getSymbol();
o_arg=startAt.getSubNode(++o_rel, Node.TYPE_LAZY);
}
Node e_body = o_arg;
//
// Rechercher la forme [with lazy/scope] et/ou [from lazy/scope]
//
Node e_with=null;
Node e_yield=null;
while(startAt.size()>o_rel+1){
o_arg=startAt.getSubNode(++o_rel, Node.TYPE_PCODE);
if(o_arg.isPCode(PCoder.PC_WITH))
if(e_with!=null)
throw new InterpreterException(StdErrors.extend(StdErrors.Duplicate_parameters,o_arg.toString()));
else{
e_with=startAt.getSubNode(++o_rel, Node.TYPE_LAZY|Node.TYPE_SCOPE);
if(e_with.isLazy())
e_with=Node.createScope(e_with);
}
else if(o_arg.isPCode(PCoder.PC_YIELD))
if(e_yield!=null)
throw new InterpreterException(StdErrors.extend(StdErrors.Duplicate_parameters,o_arg.toString()));
else{
e_yield=startAt.getSubNode(++o_rel, Node.TYPE_LAZY|Node.TYPE_SCOPE);
if(e_yield.isLazy())
e_yield=Node.createScope(e_yield);
}
}
//
// On a tout ce qu'il faut...
//
startAt.isGoodArgsCnt(o_rel+1); // Vérifie la forme
Node e_function = Node.createFunction(e_body,e_yield,e_with);
if(e_symbole!=null){
if (e_final && !e_symbole.isImmutable())
throw new InterpreterException(StdErrors.Immutable_symbol_required);
Heap.defv(e_symbole, e_function.letFinal(e_symbole.isImmutable()));
return null;
}
else
return e_function.letFinal(e_final);