@@ -1603,7 +1603,88 @@ namespace lib {
16031603 }
16041604 return int_fun (e);
16051605 }
1606+ // LAMBDAS
1607+ static std::map<unsigned int , int > lambdaFunMemory;
1608+ static std::map<unsigned int , int > lambdaProMemory;
1609+
1610+ // deemed dangerous, but should be enough to uniquely identify if 2 lambdas are the same
1611+ unsigned int JSHash (const std::string& str)
1612+ {
1613+ unsigned int hash = 1315423911 ;
16061614
1615+ for (std::size_t i = 0 ; i < str.length (); i++)
1616+ {
1617+ hash ^= ((hash << 5 ) + str[i] + (hash >> 2 ));
1618+ }
1619+
1620+ return (hash & 0x7FFFFFFF );
1621+ }
1622+
1623+ BaseGDL* lambda_fun (EnvT* e) {
1624+ static const std::string EOL (" \n " );
1625+ static int lambdanum=1 ;
1626+ DStringGDL* GDLexpr = e->GetParAs <DStringGDL>(0 );
1627+ DString expr=(*GDLexpr)[0 ];
1628+ unsigned int hash=JSHash (expr);
1629+ std::map<unsigned int ,int >::iterator it;
1630+ it = lambdaFunMemory.find (hash);
1631+ if (it != lambdaFunMemory.end ()) return new DStringGDL (" IDL$LAMBDAF" +i2s ((*it).second ));
1632+
1633+ size_t pos=expr.find (" :" ,0 );
1634+ if (pos==std::string::npos) e->Throw (" Code must be of the form \" arg1,arg2,... : statement\" " );
1635+ std::string arguments=expr.substr (0 ,pos);
1636+ string lambdaFunName=" IDL$LAMBDAF" +i2s (lambdanum);
1637+ std::string functionText;
1638+ functionText+=" FUNCTION " ;
1639+ functionText+=lambdaFunName;
1640+ functionText+=" ," ;
1641+ functionText+=arguments;
1642+ functionText+=EOL;
1643+ functionText+=" COMPILE_OPT IDL2, hidden\n RETURN," ;
1644+ functionText+=expr.substr (pos+1 );
1645+ functionText+=EOL;
1646+ functionText+=" END" ;
1647+ bool ok=GDLInterpreter::CompileFile (functionText," " , false , true );
1648+ if (!ok) e->Throw (" Syntax error in code." );
1649+
1650+ lambdaFunMemory.insert (std::pair<unsigned int ,int >(hash,lambdanum));
1651+ lambdanum++;
1652+ return new DStringGDL (lambdaFunName);
1653+ }
1654+
1655+ BaseGDL* lambda_pro (EnvT* e) {
1656+ static const std::string EOL (" \n " );
1657+ static int lambdanum=1 ;
1658+ DStringGDL* GDLexpr = e->GetParAs <DStringGDL>(0 );
1659+ DString expr=(*GDLexpr)[0 ];
1660+ unsigned int hash=JSHash (expr);
1661+ std::map<unsigned int ,int >::iterator it;
1662+ it = lambdaProMemory.find (hash);
1663+ if (it != lambdaProMemory.end ()) return new DStringGDL (" IDL$LAMBDAP" +i2s ((*it).second ));
1664+
1665+ size_t pos=expr.find (" :" ,0 );
1666+ if (pos==std::string::npos) e->Throw (" Code must be of the form \" arg1,arg2,... : statement\" " );
1667+ std::string arguments=expr.substr (0 ,pos);
1668+ string lambdaProName=" IDL$LAMBDAP" +i2s (lambdanum);
1669+ std::string proText;
1670+ proText+=" PRO " ;
1671+ proText+=lambdaProName;
1672+ proText+=" ," ;
1673+ proText+=arguments;
1674+ proText+=EOL;
1675+ proText+=" COMPILE_OPT IDL2, hidden" ;
1676+ proText+=EOL;
1677+ proText+=expr.substr (pos+1 );
1678+ proText+=EOL;
1679+ proText+=" END" ;
1680+ bool ok=GDLInterpreter::CompileFile (proText," " , false , true );
1681+ if (!ok) e->Throw (" Syntax error in code." );
1682+
1683+ lambdaProMemory.insert (std::pair<unsigned int ,int >(hash,lambdanum));
1684+ lambdanum++;
1685+ return new DStringGDL (lambdaProName);
1686+ }
1687+
16071688 BaseGDL* call_function (EnvT* e) {
16081689 int nParam = e->NParam ();
16091690 if (nParam == 0 )
0 commit comments