Phasor 2.2.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 <filesystem>
8#include <fstream>
9#include <iostream>
10#include <sstream>
11
12namespace Phasor
13{
14
15Compiler::Compiler(int argc, char *argv[], char *envp[])
16{
17 m_args.envp = envp;
18 parseArguments(argc, argv);
19}
20
22{
23 if (m_args.showLogo) std::cout << "Phasor Compiler\n(C) 2026 Daniel McGuire\n\n";
24 if (m_args.inputFile.empty())
25 {
26 std::cerr << "Error: No input file provided\n";
27 return 1;
28 }
29
30 if (m_args.irMode)
31 return compileToIR();
32
33 return compileToBytecode();
34}
35
37{
38 if (std::filesystem::path(m_args.inputFile).extension() == ".phsb")
39 {
40 std::cerr << "Error: Cannot compile a bytecode file\n";
41 return 1;
42 }
43
44 std::ifstream file(m_args.inputFile);
45 if (!file.is_open())
46 {
47 std::cerr << "Could not open file: " << m_args.inputFile << "\n";
48 return 1;
49 }
50
51 std::stringstream buffer;
52 buffer << file.rdbuf();
53 std::string source = buffer.str();
54
55 try
56 {
57 Lexer lexer(source);
58 Parser parser(lexer.tokenize());
59 auto program = parser.parse();
60 CodeGenerator codegen;
61 auto bytecode = codegen.generate(*program);
62
63 if (m_args.outputFile.empty())
64 {
65 m_args.outputFile = m_args.inputFile;
66 std::filesystem::path path(m_args.outputFile);
67 path.replace_extension(".phsb");
68 m_args.outputFile = path.string();
69 }
70
71 BytecodeSerializer serializer;
72 if (!serializer.saveToFile(bytecode, m_args.outputFile))
73 {
74 std::cerr << "Failed to save bytecode to: " << m_args.outputFile << "\n";
75 return 1;
76 }
77
78 if (m_args.showLogo) std::cout << "Compiled successfully: " << m_args.inputFile << " -> " << m_args.outputFile << "\n";
79 return 0;
80 }
81 catch (const std::exception &e)
82 {
83 std::cerr << "Compilation Error: " << e.what() << "\n";
84 return 1;
85 }
86}
87
89{
90 if (std::filesystem::path(m_args.inputFile).extension() == ".phir")
91 {
92 std::cerr << "Error: Cannot compile a Phasor IR file\n";
93 return 1;
94 }
95
96 std::ifstream file(m_args.inputFile);
97 if (!file.is_open())
98 {
99 std::cerr << "Could not open file: " << m_args.inputFile << "\n";
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 {
117 m_args.outputFile = m_args.inputFile;
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::cerr << "Failed to save Phasor IR to: " << m_args.outputFile << "\n";
126 return 1;
127 }
128
129 std::cout << "Compiled successfully to IR: " << m_args.inputFile << " -> " << m_args.outputFile << "\n";
130 return 0;
131 }
132 catch (const std::exception &e)
133 {
134 std::cerr << "Compilation Error: " << e.what() << "\n";
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 == "--no-logo")
151 {
152 m_args.showLogo = false;
153 }
154 else if (arg == "-o" || arg == "--output")
155 {
156 if (i + 1 < argc)
157 {
158 m_args.outputFile = argv[++i];
159 }
160 else
161 {
162 std::cerr << "Error: " << arg << " requires an argument\n";
163 exit(1);
164 }
165 }
166 else if (arg == "-i" || arg == "--ir")
167 {
168 m_args.irMode = true;
169 }
170 else if (arg == "-h" || arg == "--help")
171 {
172 showHelp(argv[0]);
173 exit(0);
174 }
175 else
176 {
177 defaultArgLocation = i;
178 m_args.inputFile = arg;
179 break; // Stop parsing after finding the input file
180 }
181 }
182 m_args.scriptArgv = argv + defaultArgLocation;
183 m_args.scriptArgc = argc - defaultArgLocation;
184}
185
186void Compiler::showHelp(const std::string &programName)
187{
188 std::string filename = std::filesystem::path(programName).filename().string();
189 std::cout << "Phasor Compiler\n\n";
190 std::cout << "Usage:\n";
191 std::cout << " " << filename << " [options] <file.phs>\n\n";
192 std::cout << "Options:\n";
193 std::cout << " -o, --output FILE Specify output file\n";
194 std::cout << " -i, --ir Compile to IR format (.phir) instead of bytecode\n";
195 std::cout << " -v, --verbose Enable verbose output\n";
196 std::cout << " -h, --help Show this help message\n";
197}
198
199} // namespace Phasor
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:243
Bytecode generate(const AST::Program &program, const std::map< std::string, int > &existingVars={}, int nextVarIdx=0, bool replMode=false)
Generate bytecode from program.
Definition CodeGen.cpp:7
Compiler(int argc, char *argv[], char *envp[])
Definition Compiler.cpp:15
void showHelp(const std::string &programName)
Definition Compiler.cpp:186
void parseArguments(int argc, char *argv[])
Definition Compiler.cpp:139
struct Phasor::Compiler::Args m_args
int compileToBytecode()
Definition Compiler.cpp:36
Lexer.
Definition Lexer.hpp:30
std::vector< Token > tokenize()
Definition Lexer.cpp:25
Parser.
Definition Parser.hpp:12
std::unique_ptr< AST::Program > parse()
Definition Parser.cpp:13
static bool saveToFile(const Bytecode &bytecode, const std::filesystem::path &filename)
Save bytecode to .phir file.
Definition PhasorIR.cpp:764
The Phasor Programming Language and Runtime.
Definition AST.hpp:8