Minsky
minsky::anonymous_namespace{mdlReader.cc} Namespace Reference

Classes

struct  FunctionDef
 

Functions

string readToken (istream &mdlFile, char delim, bool appendDelim=false)
 
bool identifierChar (int c)
 
string collapseWS (const string &x)
 
regex identifier (R"([A-Za-z][A-Za-z0-9._]*[A-Za-z0-9_])")
 
void addDefinitionToPort (Group &group, const shared_ptr< Port > &port, const string &name, const string &definition)
 
void defineLookupFunction (Group &group, const std::string &name, const std::string &data)
 

Variables

map< string, FunctionDefvenSimFunctions
 
set< string > functionsAdded
 

Function Documentation

◆ addDefinitionToPort()

void minsky::anonymous_namespace{mdlReader.cc}::addDefinitionToPort ( Group group,
const shared_ptr< Port > &  port,
const string &  name,
const string &  definition 
)

Definition at line 166 of file mdlReader.cc.

References f, functionsAdded, identifier(), and venSimFunctions.

Referenced by minsky::readMdl().

167  {
168  smatch match;
169  if (regex_match(definition,match,identifier))
170  {
171  const VariablePtr rhs(VariableBase::flow, definition);
172  group.addItem(rhs);
173  if (port)
174  group.addWire(rhs->ports(0).lock(), port);
175  return;
176  }
177 
178  auto function=new UserFunction(name,definition);
179  group.addItem(function); //ownership passed
180  for (auto& i: function->symbolNames())
181  {
182  auto f=venSimFunctions.find(i);
183  if (f!=venSimFunctions.end())
184  {
185  if (functionsAdded.insert(f->first).second)
186  addDefinitionToPort(group,nullptr,f->first+f->second.args,f->second.expression);
187  }
188  }
189  if (port)
190  group.addWire(function->ports(0), port);
191  }
function f
Definition: canvas.m:1
map< string, FunctionDef > venSimFunctions
Definition: mdlReader.cc:143
void addDefinitionToPort(Group &group, const shared_ptr< Port > &port, const string &name, const string &definition)
Definition: mdlReader.cc:166
regex identifier(R"([A-Za-z][A-Za-z0-9._]*[A-Za-z0-9_])")
Definition: group.tcl:84
Here is the call graph for this function:
Here is the caller graph for this function:

◆ collapseWS()

string minsky::anonymous_namespace{mdlReader.cc}::collapseWS ( const string &  x)

Definition at line 69 of file mdlReader.cc.

References identifierChar(), and minsky::to_string().

Referenced by minsky::readMdl().

70  {
71  // work in UTF-32 to simplify string analysis
72  auto xx=utf_to_utf<uint32_t>(x);
73  basic_string<uint32_t> result;
74  uint32_t lastNonWS=0;
75  bool quoted=false, lastWS=false, inIdentifier=false;
76  for (auto& i: xx)
77  {
78  if (i=='"' &&lastNonWS!='\\')
79  {
80  quoted=!quoted;
81  inIdentifier=quoted;
82  // identifiers not allowed to end in .
83  if (!inIdentifier && result.back()=='.')
84  result.erase(result.end()-1);
85  continue; // strip quotes
86  }
87 
88  if (!quoted && !inIdentifier && isalpha(i))
89  inIdentifier=true;
90  if (!quoted && inIdentifier && !identifierChar(i) && !isspace(i) && i!='_')
91  {
92  // identifiers not allowed to end in .
93  if (result.back()=='.')
94  result.erase(result.end()-1);
95  inIdentifier=false;
96  }
97 
98  if (!isspace(i) && i!='_')
99  {
100  // convert verboten characters into ones more friendly to exprtk
101  // we use . as an escape into a numerical unicode code uXXXX, terminated by another .
102  basic_string<uint32_t> exprTkGoodChar;
103  if (inIdentifier)
104  exprTkGoodChar=utf_to_utf<uint32_t>(".u"+to_string(i)+".");
105  else
106  exprTkGoodChar+=i;
107  // camelcase if collapsing whitespace in an identifier, ' ' otherwise
108  if (lastWS)
109  if (quoted || (identifierChar(i) && identifierChar(lastNonWS)))
110  if (isalnum(i))
111  result+=toupper(i);
112  else
113  result+=exprTkGoodChar;
114  else
115  {
116  result+=' ';
117  if (isalnum(i))
118  result+=tolower(i);
119  else
120  result+=exprTkGoodChar;
121  }
122  else
123  if (isalnum(i))
124  result+=tolower(i);
125  else
126  result+=exprTkGoodChar;
127  lastNonWS=i;
128  lastWS=false;
129  }
130  else
131  lastWS=true;
132  }
133  return utf_to_utf<char>(result);
134  }
string to_string(CONST84 char *x)
Definition: minskyTCLObj.h:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ defineLookupFunction()

void minsky::anonymous_namespace{mdlReader.cc}::defineLookupFunction ( Group group,
const std::string &  name,
const std::string &  data 
)

Definition at line 193 of file mdlReader.cc.

References f, and minsky::str().

Referenced by minsky::readMdl().

194  {
195  const regex lookupPairsPattern(R"((\[[^\]]*\],)?(\(.*\)))");
196  smatch match;
197  map<double,double> xData;
198  if (regex_match(data,match,lookupPairsPattern))
199  {
200  const regex extractHead(R"(\(([^,]*),([^)]*)\)(,(\(.*\)))*)");
201  // note match[3] is the trailing data, match[4] strips the leading ,
202  for (auto d=match[2].str(); regex_match(d, match, extractHead); d=match[4])
203  xData[stod(match[1])]=stod(match[2]);
204  }
205  else
206  {
207  vector<double> xyData;
208  for (size_t offs=0; offs<data.size(); ++offs)
209  xyData.push_back(stod(data.substr(offs),&offs));
210  if (xyData.size()%2!=0)
211  throw runtime_error("Odd amount of data specified");
212  for (size_t i=0; i<xyData.size()/2; ++i)
213  xData[xyData[i]]=xyData[i+xyData.size()/2];
214  }
215  auto f=make_shared<Group>();
216  f->self=f;
217  f->title=name;
218  group.addItem(f);
219  const VariablePtr dataVar(VariableType::flow,"data");
220  f->addItem(dataVar);
221  dataVar->moveTo(f->x()-50,f->y()-20);
222  const OperationPtr gather(OperationType::gather);
223  f->addItem(gather);
224  gather->moveTo(f->x()+30,f->y()-10);
225  const VariablePtr inVar(VariableType::flow,"in"), outVar(VariableType::flow,"out");
226  f->addItem(inVar);
227  f->addItem(outVar);
228  f->inVariables.push_back(inVar);
229  f->outVariables.push_back(outVar);
230  f->addWire(*dataVar, *gather, 1);
231  f->addWire(*f->inVariables[0], *gather, 2);
232  f->addWire(*gather, *f->outVariables[0], 1);
233 
234  XVector xVals("0",{Dimension::value,""});
235  auto& tensorInit=dataVar->vValue()->tensorInit;
236  for (auto& i: xData)
237  xVals.push_back(i.first);
238  Hypercube hc; hc.xvectors.push_back(std::move(xVals));
239  tensorInit.hypercube(std::move(hc));
240 
241  assert(tensorInit.size()==xData.size());
242  auto j=tensorInit.begin();
243  for (auto& i: xData)
244  *j++=i.second;
245 
246  *dataVar->vValue()=tensorInit;
247  }
function f
Definition: canvas.m:1
std::string str(T x)
utility function to create a string representation of a numeric type
Definition: str.h:33
Definition: group.tcl:84
Here is the call graph for this function:
Here is the caller graph for this function:

◆ identifier()

regex minsky::anonymous_namespace{mdlReader.cc}::identifier ( R"([A-Za-z][A-Za-z0-9._]*[A-Za-z0-9_])"  )

Referenced by addDefinitionToPort(), and minsky::readMdl().

Here is the caller graph for this function:

◆ identifierChar()

bool minsky::anonymous_namespace{mdlReader.cc}::identifierChar ( int  c)

Definition at line 63 of file mdlReader.cc.

Referenced by collapseWS().

64  {return c>0x7f || isalnum(c) || c=='\'' || c=='$';}
Here is the caller graph for this function:

◆ readToken()

string minsky::anonymous_namespace{mdlReader.cc}::readToken ( istream &  mdlFile,
char  delim,
bool  appendDelim = false 
)

Definition at line 35 of file mdlReader.cc.

Referenced by minsky::readMdl().

36  {
37  string r;
38  string c;
39  while (mdlFile>>GetUtf8Char(c))
40  if (c[0]==delim || c[0]=='~' || c[0]=='|')
41  {
42  if (appendDelim)
43  r+=c[0];
44  break;
45  }
46  else if (c[0]=='{') /* inline comment - read up to close brace */
47  {
48  while (c[0]!='}' && mdlFile>>GetUtf8Char(c));
49  continue;
50  }
51  else if (c[0]=='\\')
52  // quoted end of line processing
53  if (mdlFile>>GetUtf8Char(c) && (c[0]=='\n'||c[0]=='\r'))
54  r+=c;
55  else
56  r+="\\"+c;
57  else if (c[0]>=' ') // strip out control characters
58  r+=c;
59 
60  return r;
61  }
Here is the caller graph for this function:

Variable Documentation

◆ functionsAdded

set<string> minsky::anonymous_namespace{mdlReader.cc}::functionsAdded

Definition at line 163 of file mdlReader.cc.

Referenced by addDefinitionToPort(), and minsky::readMdl().

◆ venSimFunctions

map<string, FunctionDef> minsky::anonymous_namespace{mdlReader.cc}::venSimFunctions
Initial value:
={
{"arccos",{"(x)","acos(x)"}},
{"arcsin",{"(x)","asin(x)"}},
{"arctan",{"(x)","atan(x)"}},
{"gammaLn",{"(x)","gammaLn(x)"}},
{"integer",{"(x)","floor(x)"}},
{"ifThenElse",{"(x,y,z)","x? y: z"}},
{"ln",{"(x)","log(x)"}},
{"log",{"(x,y)","log(x)/log(y)"}},
{"modulo",{"(x,y)","x%y"}},
{"power",{"(x,y)","x^y"}},
{"pulse",{"(x,y)","(time>=x)*(time<x+y)"}},
{"pulseTrain",{"(s,b,r,e)","tm:=time%r; (time<e)*(time>=s)*(tm<((s+b)%r))*(tm>=(s%r))"}},
{"quantum",{"(x,y)","floor(x/y)"}},
{"ramp",{"(s,a,b)","var t1:=min(a,b); var t2:=max(a,b); (clamp(t1,time,t2)-t1)*s"}},
{"step",{"(x,y)","y*(time>=x)"}},
{"xidz",{"(x,y,z)","var r:=y/z; isfinite(r)? r: x"}},
{"zidz",{"(x,y)","var r:=y/z; isfinite(r)? r:0"}}
}

Definition at line 143 of file mdlReader.cc.

Referenced by addDefinitionToPort().