yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// perfect-hash-main.cpp 2 3#include "../../source/compiler-core/slang-json-parser.h" 4#include "../../source/compiler-core/slang-json-value.h" 5#include "../../source/compiler-core/slang-lexer.h" 6#include "../../source/compiler-core/slang-perfect-hash-codegen.h" 7#include "../../source/core/slang-io.h" 8#include "../../source/core/slang-secure-crt.h" 9#include "../../source/core/slang-string-util.h" 10 11#include <stdio.h> 12 13using namespace Slang ; 14 15static SlangResult parseJson (const char * inputPath ,DiagnosticSink * sink ,JSONListener & listener ) 16{ 17auto sourceManager = sink -> getSourceManager (); 18 19String contents ; 20SLANG_RETURN_ON_FAIL (File ::readAllText (inputPath ,contents )); 21PathInfo pathInfo = PathInfo ::makeFromString (inputPath ); 22SourceFile * sourceFile = sourceManager -> createSourceFileWithString (pathInfo ,contents ); 23SourceView * sourceView = sourceManager -> createSourceView (sourceFile ,nullptr ,SourceLoc ()); 24JSONLexer lexer ; 25lexer .init (sourceView ,sink ); 26JSONParser parser ; 27SLANG_RETURN_ON_FAIL (parser .parse (& lexer ,sourceView ,& listener ,sink )); 28return SLANG_OK ; 29} 30 31// Extract from a json value, the "opname" member from all the objects in the 32// "instructions" array. 33// Returns the empty list on failure 34static List < String > extractOpNames ( 35UnownedStringSlice & error , 36const JSONValue & v , 37JSONContainer & container ) 38{ 39List < String > opnames ; 40 41// Wish we could just write à la jq 42// List<String> result = match(myJSONValue, "instructions", AsArray, "opname", AsString); 43const auto instKey = container .findKey (UnownedStringSlice ("instructions" )); 44const auto opnameKey = container .findKey (UnownedStringSlice ("opname" )); 45const auto aliasesKey = container .findKey (UnownedStringSlice ("aliases" )); 46if (!instKey ) 47 { 48error = UnownedStringSlice ("JSON parsing failed, no \"instructions\" key\n" ); 49return {}; 50 } 51if (!opnameKey ) 52 { 53error = UnownedStringSlice ("JSON parsing failed, no \"opname\" key\n" ); 54return {}; 55 } 56 57const auto instructions = container .findObjectValue (v ,instKey ); 58if (!instructions .isValid ()|| instructions .type != JSONValue ::Type ::Array ) 59 { 60error = 61UnownedStringSlice ("JSON parsing failed, no \"instructions\" member of array type\n" ); 62return {}; 63 } 64for (const auto & inst :container .getArray (instructions )) 65 { 66const auto opname = container .findObjectValue (inst ,opnameKey ); 67if (!opname .isValid ()|| opname .getKind ()!= JSONValue ::Kind ::String ) 68 { 69error = UnownedStringSlice ( 70"JSON parsing failed, no \"opname\" member of string type for instruction\n" ); 71return {}; 72 } 73opnames .add (container .getString (opname )); 74 75if (aliasesKey ) 76 { 77auto aliases = container .findObjectValue (inst ,aliasesKey ); 78if (aliases .isValid ()&& aliases .type == JSONValue ::Type ::Array ) 79 { 80for (auto & alias :container .getArray (aliases )) 81 { 82opnames .add (container .getString (alias )); 83 } 84 } 85 } 86 } 87 88return opnames ; 89} 90 91int main (int argc ,const char * const * argv ) 92{ 93using namespace Slang ; 94 95if (argc != 6 ) 96 { 97fprintf ( 98stderr , 99"Usage: %s input.grammar.json output.cpp enum-name enumerant-prefix enum-header-file\n" , 100argc >=1 ?argv [0 ] :"slang-lookup-generator" ); 101return 1 ; 102 } 103 104const char * const inPath = argv [1 ]; 105const char * const outCppPath = argv [2 ]; 106const char * const enumName = argv [3 ]; 107const char * const enumerantPrefix = argv [4 ]; 108const char * const enumHeader = argv [5 ]; 109 110RefPtr < FileWriter > writer (new FileWriter (stderr ,WriterFlag ::AutoFlush )); 111SourceManager sourceManager ; 112sourceManager .initialize (nullptr ,nullptr ); 113DiagnosticSink sink (& sourceManager ,Lexer ::sourceLocationLexer ); 114sink .writer = writer ; 115 116List < String > opnames ; 117 118if (String (inPath ).endsWith ("json" )) 119 { 120// If source is a json file parse it. 121JSONContainer container (sink .getSourceManager ()); 122JSONBuilder builder (& container ); 123if (SLANG_FAILED (parseJson (inPath ,& sink ,builder ))) 124 { 125sink .diagnoseRaw (Severity ::Error ,"Json parsing failed\n" ); 126return 1 ; 127 } 128 129UnownedStringSlice error ; 130opnames = extractOpNames (error ,builder .getRootValue (),container ); 131if (error .getLength ()) 132 { 133sink .diagnoseRaw (Severity ::Error ,error ); 134return 1 ; 135 } 136 } 137else 138 { 139// Otherwise, we assume the input is a text file with one name per line. 140String content ; 141File ::readAllText (inPath ,content ); 142List < UnownedStringSlice > words ; 143StringUtil ::split (content .getUnownedSlice (),'\n' ,words ); 144for (auto w :words ) 145opnames .add (w ); 146 } 147 148if (SLANG_FAILED (writePerfectHashLookupCppFile ( 149outCppPath , 150opnames , 151enumName , 152enumerantPrefix , 153enumHeader , 154& sink ))) 155return -1 ; 156 157return 0 ; 158}