mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 14:25:44 +08:00
Add Luau.Ast.CLI target (#345)
Adds a `luau-ast` CLI that dumps Luau source to JSON. @asajeffrey and I are planning to use this functionality to construct an Agda model of the Luau type system/operational semantics, to allow formally proving properties of Luau's type systems.
This commit is contained in:
parent
e51ff38d19
commit
7ffb5fc4fd
84
CLI/Ast.cpp
Normal file
84
CLI/Ast.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "Luau/Common.h"
|
||||||
|
#include "Luau/Ast.h"
|
||||||
|
#include "Luau/JsonEncoder.h"
|
||||||
|
#include "Luau/Parser.h"
|
||||||
|
#include "Luau/ParseOptions.h"
|
||||||
|
|
||||||
|
#include "FileUtils.h"
|
||||||
|
|
||||||
|
static void displayHelp(const char* argv0)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [file]\n", argv0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int assertionHandler(const char* expr, const char* file, int line, const char* function)
|
||||||
|
{
|
||||||
|
printf("%s(%d): ASSERTION FAILED: %s\n", file, line, expr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
Luau::assertHandler() = assertionHandler;
|
||||||
|
|
||||||
|
for (Luau::FValue<bool>* flag = Luau::FValue<bool>::list; flag; flag = flag->next)
|
||||||
|
if (strncmp(flag->name, "Luau", 4) == 0)
|
||||||
|
flag->value = true;
|
||||||
|
|
||||||
|
if (argc >= 2 && strcmp(argv[1], "--help") == 0)
|
||||||
|
{
|
||||||
|
displayHelp(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (argc < 2)
|
||||||
|
{
|
||||||
|
displayHelp(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* name = argv[1];
|
||||||
|
std::optional<std::string> maybeSource = std::nullopt;
|
||||||
|
if (strcmp(name, "-") == 0)
|
||||||
|
{
|
||||||
|
maybeSource = readStdin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maybeSource = readFile(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maybeSource)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Couldn't read source %s\n", name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string source = *maybeSource;
|
||||||
|
|
||||||
|
Luau::Allocator allocator;
|
||||||
|
Luau::AstNameTable names(allocator);
|
||||||
|
|
||||||
|
Luau::ParseOptions options;
|
||||||
|
options.supportContinueStatement = true;
|
||||||
|
options.allowTypeAnnotations = true;
|
||||||
|
options.allowDeclarationSyntax = true;
|
||||||
|
|
||||||
|
Luau::ParseResult parseResult = Luau::Parser::parse(source.data(), source.size(), names, allocator, options);
|
||||||
|
|
||||||
|
if (parseResult.errors.size() > 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Parse errors were encountered:\n");
|
||||||
|
for (const Luau::ParseError& error : parseResult.errors)
|
||||||
|
{
|
||||||
|
fprintf(stderr, " %s - %s\n", toString(error.getLocation()).c_str(), error.getMessage().c_str());
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s", Luau::toJson(parseResult.root).c_str());
|
||||||
|
|
||||||
|
return parseResult.errors.size() > 0 ? 1 : 0;
|
||||||
|
}
|
@ -21,10 +21,12 @@ add_library(isocline STATIC)
|
|||||||
if(LUAU_BUILD_CLI)
|
if(LUAU_BUILD_CLI)
|
||||||
add_executable(Luau.Repl.CLI)
|
add_executable(Luau.Repl.CLI)
|
||||||
add_executable(Luau.Analyze.CLI)
|
add_executable(Luau.Analyze.CLI)
|
||||||
|
add_executable(Luau.Ast.CLI)
|
||||||
|
|
||||||
# This also adds target `name` on Linux/macOS and `name.exe` on Windows
|
# This also adds target `name` on Linux/macOS and `name.exe` on Windows
|
||||||
set_target_properties(Luau.Repl.CLI PROPERTIES OUTPUT_NAME luau)
|
set_target_properties(Luau.Repl.CLI PROPERTIES OUTPUT_NAME luau)
|
||||||
set_target_properties(Luau.Analyze.CLI PROPERTIES OUTPUT_NAME luau-analyze)
|
set_target_properties(Luau.Analyze.CLI PROPERTIES OUTPUT_NAME luau-analyze)
|
||||||
|
set_target_properties(Luau.Ast.CLI PROPERTIES OUTPUT_NAME luau-ast)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LUAU_BUILD_TESTS)
|
if(LUAU_BUILD_TESTS)
|
||||||
@ -98,6 +100,7 @@ endif()
|
|||||||
if(LUAU_BUILD_CLI)
|
if(LUAU_BUILD_CLI)
|
||||||
target_compile_options(Luau.Repl.CLI PRIVATE ${LUAU_OPTIONS})
|
target_compile_options(Luau.Repl.CLI PRIVATE ${LUAU_OPTIONS})
|
||||||
target_compile_options(Luau.Analyze.CLI PRIVATE ${LUAU_OPTIONS})
|
target_compile_options(Luau.Analyze.CLI PRIVATE ${LUAU_OPTIONS})
|
||||||
|
target_compile_options(Luau.Ast.CLI PRIVATE ${LUAU_OPTIONS})
|
||||||
|
|
||||||
target_include_directories(Luau.Repl.CLI PRIVATE extern extern/isocline/include)
|
target_include_directories(Luau.Repl.CLI PRIVATE extern extern/isocline/include)
|
||||||
|
|
||||||
@ -111,6 +114,8 @@ if(LUAU_BUILD_CLI)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(Luau.Analyze.CLI PRIVATE Luau.Analysis)
|
target_link_libraries(Luau.Analyze.CLI PRIVATE Luau.Analysis)
|
||||||
|
|
||||||
|
target_link_libraries(Luau.Ast.CLI PRIVATE Luau.Ast Luau.Analysis)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LUAU_BUILD_TESTS)
|
if(LUAU_BUILD_TESTS)
|
||||||
|
@ -193,6 +193,13 @@ if(TARGET Luau.Analyze.CLI)
|
|||||||
CLI/Analyze.cpp)
|
CLI/Analyze.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (TARGET Luau.Ast.CLI)
|
||||||
|
target_sources(Luau.Ast.CLI PRIVATE
|
||||||
|
CLI/FileUtils.h
|
||||||
|
CLI/FileUtils.cpp
|
||||||
|
CLI/Ast.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(TARGET Luau.UnitTest)
|
if(TARGET Luau.UnitTest)
|
||||||
# Luau.UnitTest Sources
|
# Luau.UnitTest Sources
|
||||||
target_sources(Luau.UnitTest PRIVATE
|
target_sources(Luau.UnitTest PRIVATE
|
||||||
|
Loading…
Reference in New Issue
Block a user