#!/usr/bin/env ruby
require 'erb'
require 'ostruct'
require 'set'
keywords = [
{
"abstract" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ABSTRACT"],
"any" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ANY"],
"arguments" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ARGUMENTS"],
"as" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_AS"],
"asserts" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ASSERTS"],
"async" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ASYNC"],
"await" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_AWAIT"],
"accessor" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ACCESSOR"],
},
{
"bigint" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BIGINT"],
"boolean" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BOOLEAN"],
"break" => ["TokenType::KEYW_BREAK", "TokenType::KEYW_BREAK"],
},
{
"case" => ["TokenType::KEYW_CASE", "TokenType::KEYW_CASE"],
"catch" => ["TokenType::KEYW_CATCH", "TokenType::KEYW_CATCH"],
"class" => ["TokenType::KEYW_CLASS", "TokenType::KEYW_CLASS"],
"const" => ["TokenType::KEYW_CONST", "TokenType::KEYW_CONST"],
"continue" => ["TokenType::KEYW_CONTINUE", "TokenType::KEYW_CONTINUE"]
},
{
"debugger" => ["TokenType::KEYW_DEBUGGER", "TokenType::KEYW_DEBUGGER"],
"declare" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_DECLARE"],
"default" => ["TokenType::KEYW_DEFAULT", "TokenType::KEYW_DEFAULT"],
"delete" => ["TokenType::KEYW_DELETE", "TokenType::KEYW_DELETE"],
"do" => ["TokenType::KEYW_DO", "TokenType::KEYW_DO"],
},
{
"else" => ["TokenType::KEYW_ELSE", "TokenType::KEYW_ELSE"],
"enum" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ENUM"],
"eval" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_EVAL"],
"export" => ["TokenType::KEYW_EXPORT", "TokenType::KEYW_EXPORT"],
"extends" => ["TokenType::KEYW_EXTENDS", "TokenType::KEYW_EXTENDS"],
},
{
"false" => ["TokenType::LITERAL_FALSE", "TokenType::LITERAL_FALSE"],
"finally" => ["TokenType::KEYW_FINALLY", "TokenType::KEYW_FINALLY"],
"for" => ["TokenType::KEYW_FOR", "TokenType::KEYW_FOR"],
"from" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_FROM"],
"function" => ["TokenType::KEYW_FUNCTION", "TokenType::KEYW_FUNCTION"],
},
{
"get" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GET"],
"global" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GLOBAL"],
},
{
"if" => ["TokenType::KEYW_IF", "TokenType::KEYW_IF"],
"implements" => ["TokenType::KEYW_IMPLEMENTS", "TokenType::KEYW_IMPLEMENTS"],
"import" => ["TokenType::KEYW_IMPORT", "TokenType::KEYW_IMPORT"],
"in" => ["TokenType::KEYW_IN", "TokenType::KEYW_IN"],
"infer" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INFER"],
"instanceof" => ["TokenType::KEYW_INSTANCEOF", "TokenType::KEYW_INSTANCEOF"],
"interface" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INTERFACE"],
"is" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_IS"],
},
{
"keyof" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_KEYOF"],
},
{
"lazy" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_LAZY"],
"let" => ["TokenType::KEYW_LET", "TokenType::KEYW_LET"],
},
{
"meta" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_META"],
"module" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_MODULE"],
"namespace" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NAMESPACE"],
},
{
"never" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NEVER"],
"new" => ["TokenType::KEYW_NEW", "TokenType::KEYW_NEW"],
"null" => ["TokenType::LITERAL_NULL", "TokenType::LITERAL_NULL"],
"number" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NUMBER"],
},
{
"object" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OBJECT"],
"of" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OF"],
"out" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OUT"],
"override" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OVERRIDE"],
},
{
"package" => ["TokenType::KEYW_PACKAGE", "TokenType::KEYW_PACKAGE"],
"private" => ["TokenType::KEYW_PRIVATE", "TokenType::KEYW_PRIVATE"],
"protected" => ["TokenType::KEYW_PROTECTED", "TokenType::KEYW_PROTECTED"],
"public" => ["TokenType::KEYW_PUBLIC", "TokenType::KEYW_PUBLIC"],
},
{
"readonly" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_READONLY"],
"return" => ["TokenType::KEYW_RETURN", "TokenType::KEYW_RETURN"],
"require" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_REQUIRE"],
},
{
"satisfies" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SATISFIES"],
"set" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SET"],
"static" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STATIC"],
"string" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STRING"],
"super" => ["TokenType::KEYW_SUPER", "TokenType::KEYW_SUPER"],
"switch" => ["TokenType::KEYW_SWITCH", "TokenType::KEYW_SWITCH"],
"symbol" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SYMBOL"],
},
{
"this" => ["TokenType::KEYW_THIS", "TokenType::KEYW_THIS"],
"throw" => ["TokenType::KEYW_THROW", "TokenType::KEYW_THROW"],
"true" => ["TokenType::LITERAL_TRUE", "TokenType::LITERAL_TRUE"],
"try" => ["TokenType::KEYW_TRY", "TokenType::KEYW_TRY"],
"type" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_TYPE"],
"typeof" => ["TokenType::KEYW_TYPEOF", "TokenType::KEYW_TYPEOF"],
},
{
"undefined" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNDEFINED"],
"unique" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNIQUE"],
"unknown" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNKNOWN"],
},
{
"var" => ["TokenType::KEYW_VAR", "TokenType::KEYW_VAR"],
"void" => ["TokenType::KEYW_VOID", "TokenType::KEYW_VOID"],
},
{
"while" => ["TokenType::KEYW_WHILE", "TokenType::KEYW_WHILE"],
"with" => ["TokenType::KEYW_WITH", "TokenType::KEYW_WITH"],
},
{
"yield" => ["TokenType::KEYW_YIELD", "TokenType::KEYW_YIELD"],
},
]
def collect_functions(functions, keys)
offset = 0
while true
has_more = false
keys.each do |key|
if key.length < offset + 1
next
end
has_more = true
func_name = key[0..offset];
if functions.has_key?(func_name)
functions[func_name].add(key[offset + 1])
else
functions[func_name] = Set[key[offset + 1]]
end
end
if has_more
offset += 1
next
end
break
end
end
def generate(keywords, template_file, output_file)
functions = {}
keywords.each do |group|
collect_functions(functions, group.keys)
end
template = File.read(template_file)
t = ERB.new(template, nil, '%-')
t.filename = OpenStruct.new.template
res = t.result(binding)
File.open(output_file, "w") do |file|
file.write(res)
end
end
abort "Failed: input file required!" if ARGV.size < 2
generate(keywords, ARGV[0], ARGV[1])