Skip to content
Snippets Groups Projects
Commit 7cdf028b authored by Mattias Ajander's avatar Mattias Ajander
Browse files

Merge branch 'main' into feature-args

parents 0985e1ca 6106ca91
Branches
No related tags found
No related merge requests found
...@@ -75,6 +75,8 @@ ...@@ -75,6 +75,8 @@
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp", "typeinfo": "cpp",
"valarray": "cpp", "valarray": "cpp",
"variant": "cpp" "variant": "cpp",
"*.def": "cpp",
"*.inc": "cpp"
} }
} }
...@@ -9,9 +9,10 @@ Funk is a custom programming language with its own interpreter. It was developed ...@@ -9,9 +9,10 @@ Funk is a custom programming language with its own interpreter. It was developed
- Static typing system - Static typing system
- Built-in error handling - Built-in error handling
- Comprehensive logging system - Comprehensive logging system
- REPL for interactive programming
## Project Structure ## Project Structure
```zsh ```sh
funk/ funk/
├── .vscode/ # VSCode settings and configurations ├── .vscode/ # VSCode settings and configurations
├── bin/ # Binary files (generated by make) ├── bin/ # Binary files (generated by make)
...@@ -19,20 +20,24 @@ funk/ ...@@ -19,20 +20,24 @@ funk/
│ └── funk # Main Funk interpreter │ └── funk # Main Funk interpreter
├── build/ # Object files (generated by make) ├── build/ # Object files (generated by make)
├── docs/ # Documentation ├── docs/ # Documentation
│ ├── Language Specification/ # Typst documents for language specification
│ ├── Language Specification.pdf # Formal language specification │ ├── Language Specification.pdf # Formal language specification
│ └── html/ # Generated Doxygen documentation (after generation) │ └── html/ # Generated Doxygen documentation (after generation)
├── examples/ # Example programs
├── include/ # Header files ├── include/ # Header files
│ ├── ast/ # Abstract syntax tree
│ ├── lexer/ # Lexical analysis components │ ├── lexer/ # Lexical analysis components
│ ├── logging/ # Logging implementation
│ ├── parser/ # Syntax analysis components │ ├── parser/ # Syntax analysis components
│ └── ... # Other headers │ ├── token/ # Token implementation
│ └── utils/ # Utility functions
├── source/ # Source code ├── source/ # Source code
│ ├── lexer/ # Lexer implementation │ ├── main.cc # Main entry point
│ ├── parser/ # Parser implementation │ └── ... # Same structure as include/
│ └── ... # Other implementations
├── tests/ # Test files for each major feature ├── tests/ # Test files for each major feature
├── .clang-format # Clang format configuration ├── .clang-format # Clang format configuration
├── Doxyfile # Doxygen configuration file
├── compile+test # Script to compile and run all tests ├── compile+test # Script to compile and run all tests
├── Doxyfile # Doxygen configuration file
├── funk.log # Log file (created during execution) ├── funk.log # Log file (created during execution)
└── Makefile # Build system configuration └── Makefile # Build system configuration
``` ```
...@@ -48,38 +53,53 @@ funk/ ...@@ -48,38 +53,53 @@ funk/
### Building from Source ### Building from Source
1. Clone the repository: 1. Clone the repository:
```zsh ```sh
git clone https://gitlab.liu.se/mataj513/tdp019.git git clone https://gitlab.liu.se/mataj513/tdp019.git
cd tdp019 cd tdp019
``` ```
2. Build the interpreter: 2. Build the interpreter:
```zsh ```sh
make make
``` ```
3. For a clean build: 3. For a clean build:
```zsh ```sh
make clean make clean
make make
``` ```
4. For testing:
```sh
make tests
```
## Usage ## Usage
After building the Funk interpreter, you can use it in the following ways: After building the Funk interpreter, you can use it in the following ways:
### Running Funk Programs ### Running Funk Programs
To execute a Funk program file: To execute a Funk program file:
```zsh ```sh
./bin/funk <path_to_file> ./bin/funk <path_to_file> [args]
``` ```
See examples in the [examples](examples) directory. See examples in the [examples](examples) directory.
Arguments can be passed to the program by adding them after the file path. Arguments before the file path are interpreted as arguments to the interpreter itself.
For more help and options see: For more help and options see:
```zsh ```sh
./bin/funk --help ./bin/funk --help
``` ```
### REPL
The interpreter also supports a REPL (Read-Eval-Print-Loop) mode, allowing you to interactively enter and execute Funk code.
```sh
./bin/funk
```
### Logging ### Logging
The interpreter uses a logging system to provide detailed information about its execution. The interpreter uses a logging system to provide detailed information about its execution.
The log file is located at `funk.log` but can be changed by adding `--log new/path.log` to the program. The log file is located at `funk.log` but can be changed by adding `--log new/path.log` to the program.
...@@ -88,17 +108,17 @@ The log file is located at `funk.log` but can be changed by adding `--log new/pa ...@@ -88,17 +108,17 @@ The log file is located at `funk.log` but can be changed by adding `--log new/pa
Funk comes with a comprehensive test suite to ensure functionality: Funk comes with a comprehensive test suite to ensure functionality:
1. Run all tests (compiles and executes tests): 1. Run all tests (compiles and executes tests):
```zsh ```sh
./compile+test ./compile+test
``` ```
2. Compile tests only: 2. Compile tests only:
```zsh ```sh
make tests make tests
``` ```
3. Run a specific test: 3. Run a specific test:
```zsh ```sh
./bin/tests/<name> ./bin/tests/<name>
``` ```
...@@ -109,7 +129,7 @@ See the [Language Specification](docs/Language%20Specification.pdf) for a formal ...@@ -109,7 +129,7 @@ See the [Language Specification](docs/Language%20Specification.pdf) for a formal
### Doxygen Documentation ### Doxygen Documentation
To generate the detailed documentation, run the following command: To generate the detailed documentation, run the following command:
```zsh ```sh
doxygen Doxyfile doxygen Doxyfile
``` ```
......
...@@ -19,7 +19,7 @@ using namespace funk; ...@@ -19,7 +19,7 @@ using namespace funk;
*/ */
HashMap<String, String> options{ HashMap<String, String> options{
{"--help", "Display this help message"}, {"--help", "Display this help message"},
{"--log <file>", "Set the log file"}, {"--log=<file>", "Set the log file"},
{"--debug", "Enable debug logging"}, {"--debug", "Enable debug logging"},
{"--ast", "Log the AST representation"}, {"--ast", "Log the AST representation"},
{"--tokens", "Log the lexical tokens"}, {"--tokens", "Log the lexical tokens"},
...@@ -123,6 +123,16 @@ void process_file(const String& file, const Config& config, const Vector<String> ...@@ -123,6 +123,16 @@ void process_file(const String& file, const Config& config, const Vector<String>
LOG_ERROR("Error processing file " + file + ": " + e.what()); LOG_ERROR("Error processing file " + file + ": " + e.what());
cerr << "Error: " << e.trace() << endl; cerr << "Error: " << e.trace() << endl;
} }
catch (const FileError& e)
{
LOG_ERROR(e.what());
cerr << e.what() << endl;
}
catch (const std::exception& e)
{
LOG_ERROR("Unknown error occurred: " + String(e.what()));
cerr << "Unknown error occurred: " << e.what() << endl;
}
} }
/** /**
......
...@@ -9,20 +9,19 @@ ArgParser::ArgParser(int argc, char* argv[]) ...@@ -9,20 +9,19 @@ ArgParser::ArgParser(int argc, char* argv[])
{ {
String arg{argv[i]}; String arg{argv[i]};
if (arg.substr(0, 2) == "--") if (!file.empty())
{ {
if (i + 1 < argc && argv[i + 1][0] != '-') args.push_back(arg);
{ continue;
options[arg] = argv[i + 1];
++i;
}
else { options[arg] = ""; }
} }
else
if (arg.substr(0, 2) == "--")
{ {
if (file.empty()) { file = arg; } size_t eq_pos = arg.find('=');
else { args.push_back(arg); } if (eq_pos != String::npos) { options[arg.substr(0, eq_pos)] = arg.substr(eq_pos + 1); }
else { options[arg] = ""; }
} }
else { file = arg; }
} }
} }
......
#include "utils/Common.h" #include "utils/Common.h"
#include "utils/Exception.h"
namespace funk namespace funk
{ {
...@@ -6,7 +7,7 @@ namespace funk ...@@ -6,7 +7,7 @@ namespace funk
String read_file(const String& filename) String read_file(const String& filename)
{ {
std::ifstream file(filename); std::ifstream file(filename);
if (!file.is_open()) { throw std::runtime_error("Failed to open file: " + filename); } if (!file.is_open()) { throw FileError("Failed to open file: " + filename); }
std::stringstream buffer; std::stringstream buffer;
buffer << file.rdbuf() << '\n'; buffer << file.rdbuf() << '\n';
return buffer.str(); return buffer.str();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment