Phasor 3.3.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
Compiler.cpp
Go to the documentation of this file.
1#include "Compiler.hpp"
7#include <version.h>
8#include <filesystem>
9#include <fstream>
10#include <print>
11#include <sstream>
12
13namespace pulsar
14{
15
16Compiler::Compiler(int argc, char *argv[])
17{
18 parseArguments(argc, argv);
19}
20
21int Compiler::run()
22{
23 if (m_args.inputFile.empty())
24 {
25 std::println(std::cerr, "Error: No input file provided");
26 return 1;
27 }
28
29 if (m_args.irMode)
30 return compileToIR();
31
32 return compileToBytecode();
33}
34
36{
37 if (std::filesystem::path(m_args.inputFile).extension() == ".phsb")
38 {
39 std::println(std::cerr, "Error: Cannot compile a bytecode file");
40 return 1;
41 }
42
43 std::ifstream file(m_args.inputFile);
44 if (!file.is_open())
45 {
46 std::println(std::cerr, "Could not open file: {}", m_args.inputFile);
47 return 1;
48 }
49
50 std::stringstream buffer;
51 buffer << file.rdbuf();
52 std::string source = buffer.str();
53
54 try
55 {
56 Lexer lexer(source);
57 Parser parser(lexer.tokenize());
58 auto program = parser.parse();
59 CodeGenerator codegen;
60 auto bytecode = codegen.generate(*program);
61
62 if (m_args.outputFile.empty())
63 {
65 std::filesystem::path path(m_args.outputFile);
66 path.replace_extension(".phsb");
67 m_args.outputFile = path.string();
68 }
69
70 BytecodeSerializer serializer;
71 if (!serializer.saveToFile(bytecode, m_args.outputFile))
72 {
73 std::println(std::cerr, "Failed to save bytecode to: {}", m_args.outputFile);
74 return 1;
75 }
76
77
78 std::println("Compiled successfully: {} -> {}", m_args.inputFile, m_args.outputFile);
79 return 0;
80 }
81 catch (const std::exception &e)
82 {
83 std::println(std::cerr, "Compilation Error: {}", e.what());
84 return 1;
85 }
86}
87
89{
90 if (std::filesystem::path(m_args.inputFile).extension() == ".phir")
91 {
92 std::println(std::cerr, "Error: Cannot compile a Phasor IR file");
93 return 1;
94 }
95
96 std::ifstream file(m_args.inputFile);
97 if (!file.is_open())
98 {
99 std::println(std::cerr, "Could not open file: {}", m_args.inputFile);
100 return 1;
101 }
102
103 std::stringstream buffer;
104 buffer << file.rdbuf();
105 std::string source = buffer.str();
106
107 try
108 {
109 Lexer lexer(source);
110 Parser parser(lexer.tokenize());
111 auto program = parser.parse();
112 CodeGenerator codegen;
113 auto bytecode = codegen.generate(*program);
114
115 if (m_args.outputFile.empty())
116 {
118 std::filesystem::path path(m_args.outputFile);
119 path.replace_extension(".phir");
120 m_args.outputFile = path.string();
121 }
122
123 if (!PhasorIR::saveToFile(bytecode, m_args.outputFile))
124 {
125 std::println(std::cerr, "Failed to save Phasor IR to: {}", m_args.outputFile);
126 return 1;
127 }
128
129 std::println("Compiled successfully to IR: {} -> {}", m_args.inputFile, m_args.outputFile);
130 return 0;
131 }
132 catch (const std::exception &e)
133 {
134 std::println(std::cerr, "Compilation Error: {}", e.what());
135 return 1;
136 }
137}
138
139void Compiler::parseArguments(int argc, char *argv[])
140{
141 int defaultArgLocation = 1;
142 for (int i = 1; i < argc; i++)
143 {
144 std::string arg = argv[i];
145
146 if (arg == "-v" || arg == "--verbose")
147 {
148 m_args.verbose = true;
149 }
150 else if (arg == "-o" || arg == "--output")
151 {
152 if (i + 1 < argc)
153 {
154 m_args.outputFile = argv[++i];
155 }
156 else
157 {
158 std::println(std::cerr, "Error: {} requires an argument", arg);
159 exit(1);
160 }
161 }
162 else if (arg == "-i" || arg == "--ir")
163 {
164 m_args.irMode = true;
165 }
166 else if (arg == "-h" || arg == "--help")
167 {
168 showHelp(argv[0]);
169 exit(0);
170 }
171 else
172 {
173 defaultArgLocation = i;
174 m_args.inputFile = arg;
175 break; // Stop parsing after finding the input file
176 }
177 }
178 m_args.scriptArgv = argv + defaultArgLocation;
179 m_args.scriptArgc = argc - defaultArgLocation;
180}
181
182void Compiler::showHelp(const std::string &programName)
183{
184 std::string filename = std::filesystem::path(programName).filename().string();
185 std::println("Pulsar Compiler (Phasor v{})\n"
186 "(C) 2026 Daniel McGuire - Licensed under Apache 2.0\n\n"
187 "Usage:\n"
188 " {} [options] <file>\n\n"
189 "Options:\n"
190 " -o, --output FILE Specify output file\n"
191 " -i, --ir Compile to IR format (.phir) instead of bytecode\n"
192 " -v, --verbose Enable verbose output\n"
193 " -h, --help Show this help message",
194 PHASOR_VERSION_STRING, filename);
195}
196
197} // namespace pulsar
Bytecode binary format serializer.
bool saveToFile(const Bytecode &bytecode, const std::filesystem::path &filename)
Save bytecode to .phsb file.
Code generator for Phasor VM.
Definition CodeGen.hpp:108
Bytecode generate(const AST::Program &program, const std::unordered_map< std::string, int > &existingVars={}, int nextVarIdx=0, bool replMode=false)
Generate bytecode from program.
Definition CodeGen.cpp:8
struct Phasor::Compiler::Args m_args
void parseArguments(int argc, char *argv[])
Definition Compiler.cpp:141
int compileToBytecode()
Definition Compiler.cpp:38
static void showHelp(const std::string &programName)
Definition Compiler.cpp:184
Lexer.
Definition Lexer.hpp:13
std::vector< Token > tokenize()
Definition Lexer.cpp:27
Parser.
Definition Parser.hpp:13
std::unique_ptr< AST::Program > parse()
Definition Parser.cpp:74
static bool saveToFile(const Bytecode &bytecode, const std::filesystem::path &filename)
Save bytecode to .phir file.
Definition PhasorIR.cpp:647
Compiler(int argc, char *argv[])
The Pulsar Scripting Language.
Definition Compiler.cpp:14
std::string inputFile
Definition Compiler.hpp:24
std::string outputFile
Definition Compiler.hpp:25