Ruby 4.1.0dev (2026-09-22 revision d41370aec5370c96a7a1a62b1be84d21347901fc)
dump_ast.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <inttypes.h>
5
6/*
7 * When prism is compiled as part of CRuby, the xmalloc/xfree/etc. macros are
8 * redirected to ruby_xmalloc/ruby_xfree/etc. Since this is a standalone
9 * program that links against those same object files, we need to provide
10 * implementations of these functions.
11 */
12void *ruby_xmalloc(size_t size) { return malloc(size); }
13void *ruby_xcalloc(size_t nelems, size_t elemsiz) { return calloc(nelems, elemsiz); }
14void *ruby_xrealloc(void *ptr, size_t newsiz) { return realloc(ptr, newsiz); }
15void ruby_xfree(void *ptr) { free(ptr); }
16void ruby_xfree_sized(void *ptr, size_t _oldsize) { free(ptr); }
17void *ruby_xrealloc_sized(void *ptr, size_t newsiz, size_t _oldsiz) { return realloc(ptr, newsiz); }
18
19#include "prism.h"
20
21static void
22print_error(const pm_diagnostic_t *diagnostic, void *data)
23{
24 const pm_parser_t *parser = (const pm_parser_t *) data;
25 pm_location_t loc = pm_diagnostic_location(diagnostic);
26 const pm_line_column_t line_column = pm_line_offset_list_line_column(pm_parser_line_offsets(parser), loc.start, pm_parser_start_line(parser));
27 fprintf(stderr, "%" PRIi32 ":%" PRIu32 ":%s\n", line_column.line, line_column.column, pm_diagnostic_message(diagnostic));
28}
29
30static void
31usage(const char *prog)
32{
33 fprintf(stderr, "Usage: %s [options]... <filename>\n"
34 "Options:\n"
35 " -v, --version: show Prism version\n"
36 " -h, --help: show this message\n"
37 "", prog);
38}
39
40int
41main(int argc, const char *argv[])
42{
43 const char *filepath = 0;
44
45 for (int i = 1; i < argc; ++i) {
46 const char *arg = argv[i];
47 if (arg[0] != '-') {
48 if (filepath) {
49 fprintf(stderr, "too many filename\n");
50 goto usage;
51 }
52 filepath = arg;
53 }
54 else if (arg[1] == '-') {
55 if (!arg[2]) break;
56 if (strcmp(arg + 2, "version") == 0) {
57 version:
58 fputs("Prism " PRISM_VERSION "\n", stdout);
59 return EXIT_SUCCESS;
60 }
61 if (strcmp(arg + 2, "help") == 0) {
62 help:
63 usage(argv[0]);
64 return EXIT_SUCCESS;
65 }
66 fprintf(stderr, "unknown option %s\n", arg);
67 goto usage;
68 }
69 else {
70 while (*++arg) {
71 switch (*arg) {
72 case 'v':
73 goto version;
74 case 'h':
75 goto help;
76 default:
77 fprintf(stderr, "unknown option -%c\n", *arg);
78 goto usage;
79 }
80 }
81 }
82 }
83
84 if (!filepath) {
85 usage:
86 usage(argv[0]);
87 return EXIT_FAILURE;
88 }
89
90 pm_source_init_result_t init_result;
91 pm_source_t *source = pm_source_mapped_new(filepath, 0, &init_result);
92
93 if (init_result != PM_SOURCE_INIT_SUCCESS) {
94 fprintf(stderr, "unable to map file: %s\n", filepath);
95 return EXIT_FAILURE;
96 }
97
98 pm_options_t *options = pm_options_new();
99 pm_options_line_set(options, 1);
100 pm_options_filepath_set(options, filepath);
101
102 pm_arena_t *arena = pm_arena_new();
103 pm_parser_t *parser = pm_parser_new(arena, pm_source_source(source), pm_source_length(source), options);
104
105 pm_node_t *node = pm_parse(parser);
106 int exit_status;
107
108 if (pm_parser_errors_size(parser) > 0)
109 {
110 fprintf(stderr, "error parsing %s\n", filepath);
111 pm_parser_errors_each(parser, print_error, parser);
112 exit_status = EXIT_FAILURE;
113 }
114 else {
115 pm_buffer_t *json = pm_buffer_new();
116 pm_dump_json(json, parser, node);
117 printf("%.*s\n", (int) pm_buffer_length(json), pm_buffer_value(json));
118 pm_buffer_free(json);
119 exit_status = EXIT_SUCCESS;
120 }
121
122 pm_parser_free(parser);
123 pm_arena_free(arena);
124 pm_source_free(source);
125 pm_options_free(options);
126
127 return exit_status;
128}
PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_parser_t * pm_parser_new(pm_arena_t *arena, const uint8_t *source, size_t size, const pm_options_t *options) PRISM_NONNULL(1)
Allocate and initialize a parser with the given start and end pointers.
Definition prism.c:23183
PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *parser) PRISM_NONNULL(1)
Free both the memory held by the given parser and the parser itself.
Definition prism.c:23216
PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser) PRISM_NONNULL(1)
Initiate the parser with the given parser.
Definition prism.c:23387
#define PRISM_VERSION
The version of the Prism library as a constant string.
Definition version.h:29
The main header file for the prism parser.
pm_source_init_result_t
Represents the result of initializing a source from a file.
Definition source.h:46
@ PM_SOURCE_INIT_SUCCESS
Indicates that the source was successfully initialized.
Definition source.h:48
A line and column in a string.
uint32_t column
The column in bytes.
int32_t line
The line number.
This struct represents a slice in the source code, defined by an offset and a length.
Definition ast.h:572
uint32_t start
The offset of the location from the start of the source.
Definition ast.h:574
This is the base structure that represents a node in the syntax tree.
Definition ast.h:1083