comparison Resources/CodeGeneration/stonegentool.py @ 493:6fbf2eae7c88 bgo-commands-codegen

All unit tests pass for generation, including handler and dispatcher
author bgo-osimis
date Fri, 22 Feb 2019 10:48:43 +0100
parents 8e7e151ef472
children fc17251477d6
comparison
equal deleted inserted replaced
491:8e7e151ef472 493:6fbf2eae7c88
106 106
107 107
108 def LoadSchemaFromJson(filePath: str): 108 def LoadSchemaFromJson(filePath: str):
109 return JsonHelpers.loadJsonWithComments(filePath) 109 return JsonHelpers.loadJsonWithComments(filePath)
110 110
111 def GetCppTypenameFromCanonical(canonicalTypename: str) -> str: 111 def CanonToCpp(canonicalTypename: str) -> str:
112 # C++: prefix map vector and string with std::map, std::vector and 112 # C++: prefix map vector and string with std::map, std::vector and
113 # std::string 113 # std::string
114 # replace int32 by int32_t 114 # replace int32 by int32_t
115 # replace float32 by float 115 # replace float32 by float
116 # replace float64 by double 116 # replace float64 by double
117 retVal: str = canonicalTypename 117 retVal: str = canonicalTypename
118 retVal = retVal.replace("map", "std::map") 118 retVal = retVal.replace("map", "std::map")
119 retVal = retVal.replace("vector", "std::vector") 119 retVal = retVal.replace("vector", "std::vector")
120 retVal = retVal.replace("int32", "int32_t") 120 retVal = retVal.replace("int32", "int32_t")
121 retVal = retVal.replace("float32", "float") 121 retVal = retVal.replace("float32", "float")
122 retVal = retVal.replace("float64", "double") 122 retVal = retVal.replace("float64", "double")
123 return retVal 123 return retVal
124 124
125 def GetTypeScriptTypenameFromCanonical(canonicalTypename: str) -> str: 125 def CanonToTs(canonicalTypename: str) -> str:
126 # TS: replace vector with Array and map with Map 126 # TS: replace vector with Array and map with Map
127 # string remains string 127 # string remains string
128 # replace int32 by number 128 # replace int32 by number
129 # replace float32 by number 129 # replace float32 by number
130 # replace float64 by number 130 # replace float64 by number
131 retVal: str = canonicalTypename 131 retVal: str = canonicalTypename
132 retVal = retVal.replace("map", "Map") 132 retVal = retVal.replace("map", "Map")
133 retVal = retVal.replace("vector", "Array") 133 retVal = retVal.replace("vector", "Array")
134 retVal = retVal.replace("int32", "number") 134 retVal = retVal.replace("int32", "number")
135 retVal = retVal.replace("float32", "number") 135 retVal = retVal.replace("float32", "number")
136 retVal = retVal.replace("float64", "number") 136 retVal = retVal.replace("float64", "number")
137 retVal = retVal.replace("bool", "boolean") 137 retVal = retVal.replace("bool", "boolean")
138 return retVal 138 return retVal
139
140 def NeedsConstruction(canonTypename):
141 return True
142
143 def RegisterTemplateFunction(template,func):
144 """Makes a function callable by a jinja2 template"""
145 template.globals[func.__name__] = func
146 return func
147
148 def MakeTemplate(templateStr):
149 template = Template(templateStr)
150 RegisterTemplateFunction(template,CanonToCpp)
151 RegisterTemplateFunction(template,CanonToTs)
152 RegisterTemplateFunction(template,NeedsConstruction)
153 return template
154
155 def MakeTemplateFromFile(templateFileName):
156 templateFile = open(templateFileName, "r")
157 templateFileContents = templateFile.read()
158 return MakeTemplate(templateFileContents)
159 templateFile.close()
139 160
140 def EatToken(sentence: str) -> Tuple[str, str]: 161 def EatToken(sentence: str) -> Tuple[str, str]:
141 """splits "A,B,C" into "A" and "B,C" where A, B and C are type names 162 """splits "A,B,C" into "A" and "B,C" where A, B and C are type names
142 (including templates) like "int32", "TotoTutu", or 163 (including templates) like "int32", "TotoTutu", or
143 "map<map<int32,vector<string>>,map<string,int32>>" """ 164 "map<map<int32,vector<string>>,map<string,int32>>" """
305 raise RuntimeError \ 326 raise RuntimeError \
306 (f'Type "{name}" should start with "enum " or "struct "') 327 (f'Type "{name}" should start with "enum " or "struct "')
307 328
308 # TODO: check enum fields are unique (in whole namespace) 329 # TODO: check enum fields are unique (in whole namespace)
309 # TODO: check struct fields are unique (in each struct) 330 # TODO: check struct fields are unique (in each struct)
331 # TODO: check that in the source schema, there are spaces after each colon
310 332
311 # +-----------------------+ 333 # +-----------------------+
312 # | Main processing logic | 334 # | Main processing logic |
313 # +-----------------------+ 335 # +-----------------------+
314 336
393 # def WriteStreamsToFiles(rootName: str, genc: Dict[str, StringIO]) \ 415 # def WriteStreamsToFiles(rootName: str, genc: Dict[str, StringIO]) \
394 # -> None: 416 # -> None:
395 # pass 417 # pass
396 418
397 def LoadSchema(fn): 419 def LoadSchema(fn):
398 with open(fn, 'rb') as f: 420 # latin-1 is a trick, when we do NOT care about NON-ascii chars but
399 schema = yaml.load(f) 421 # we wish to avoid using a decoding error handler
422 # (see http://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html#files-in-an-ascii-compatible-encoding-best-effort-is-acceptable)
423 # TL;DR: all 256 values are mapped to characters in latin-1 so the file
424 # contents never cause an error.
425 with open(fn, 'r', encoding='latin-1') as f:
426 schemaText = f.read()
427 assert(type(schemaText) == str)
428 # ensure there is a space after each colon. Otherwise, dicts could be
429 # erroneously recognized as an array of strings containing ':'
430 for i in range(len(schemaText)-1):
431 ch = schemaText[i]
432 nextCh = schemaText[i+1]
433 if ch == ':':
434 if not (nextCh == ' ' or nextCh == '\n'):
435 assert(False)
436 schema = yaml.load(schemaText)
400 return schema 437 return schema
401 438
402 def GetTemplatingDictFromSchemaFilename(fn): 439 def GetTemplatingDictFromSchemaFilename(fn):
403 obj = LoadSchema(fn) 440 obj = LoadSchema(fn)
404 genOrder: str = ComputeRequiredDeclarationOrder(obj) 441 genOrder: str = ComputeRequiredDeclarationOrder(obj)
656 # # let's generate the code according to the 693 # # let's generate the code according to the
657 # struct = schema[name] 694 # struct = schema[name]
658 695
659 # if not IsStructType(name): 696 # if not IsStructType(name):
660 # raise Exception(f'{typename} should start with "struct "') 697 # raise Exception(f'{typename} should start with "struct "')
698
699