Fixes and functions

This commit is contained in:
2025-10-01 13:43:08 +10:00
parent d137a623ed
commit 2a977707ee
8 changed files with 97 additions and 6 deletions

View File

@@ -6,7 +6,7 @@
enum class InstructionType {
None, Print, Println, Math, Let, Variable, Exit, If, While, Input, Compare
None, Print, Println, Math, Let, Variable, Exit, If, While, Input, Compare, Function
};
enum class ValueType {

View File

@@ -12,6 +12,7 @@
#include "../modules/while/while.h"
#include "../modules/compare/compare.h"
#include "../modules/input/input.h"
#include "../modules/function/function.h"
Value execute(Instruction inst) {
// Special cases that need to manage their own argument evaluation
@@ -24,6 +25,9 @@ Value execute(Instruction inst) {
if (inst.instruction == InstructionType::While) {
return modules::whiles(inst.args);
}
if (inst.instruction == InstructionType::Function) {
return modules::fndef(inst.args);
}
// For all other instructions, evaluate the arguments first
size_t i = 0;
@@ -64,7 +68,17 @@ Value execute(Instruction inst) {
case InstructionType::Exit:
return modules::exit(inst.args);
break;
case InstructionType::Variable:
case InstructionType::Variable: {
if (!inst.args.empty()) {
const std::string& name = inst.args[0].real;
if (data::functions.count(name)) {
Value return_val;
for (const auto& body_inst : data::functions.at(name)) {
return_val = execute(body_inst);
}
return return_val;
}
}
if (inst.args.size() > 2 && inst.args[1].valtype == ValueType::Real && inst.args[1].real == "=") {
return varmod(inst.args);
} else {
@@ -72,6 +86,7 @@ Value execute(Instruction inst) {
return Value("");
}
break;
}
default:
// Note: 'If' and 'Let' are already handled.
error("Unknown instruction");

View File

@@ -7,8 +7,8 @@ int main(int argc, char** argv) {
if (argc < 2) {
repl();
} else {
for (int i = 0; i < argc; i++) {
if (strcmp(argv[i], "-h") || strcmp(argv[i], "--help")) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
std::cout << "Kyn programming language" << std::endl;
std::cout << "Usage: " << argv[0] << " (filename).kyn" << std::endl;
std::cout << "Kyn is licensed to you under the Mozilla Public License v2.0" << std::endl;
@@ -16,7 +16,6 @@ int main(int argc, char** argv) {
exit(0);
}
}
execFile(argv[1]);
}
}

View File

@@ -0,0 +1,25 @@
#include "function.h"
#include "../../defs/defs.h"
#include "../../data/data.h"
#include "../../error/error.h"
#include <vector>
Value modules::fndef(std::vector<Value> args) {
if (args.size() < 2) {
error("Syntax error: function statement requires a name and a body");
return Value();
}
if (args[0].valtype != ValueType::Processed) {
error("Syntax error: function name must be a processed value");
return Value();
}
if (args[1].valtype != ValueType::InstructionGroup) {
error("Syntax error: function body must be an instruction group");
return Value();
}
std::string func_name = args[0].processed->args[0].real;
data::functions[func_name] = args[1].instructionGroup;
return Value("");
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include "../../defs/defs.h"
#include <vector>
namespace modules {
Value fndef(std::vector<Value> args);
}

View File

@@ -137,9 +137,42 @@ std::vector<Instruction> parse(std::string program) {
std::string then_content = line.substr(block_start + 1, block_end - block_start - 1);
while_inst.args.push_back(Value(parse(then_content))); // Recursive call
instructions.push_back(while_inst);
} else if (line.rfind("fun", 0) == 0) {
Instruction function_inst;
function_inst.instruction = InstructionType::Function;
size_t block_start = line.find('{');
if (block_start == std::string::npos) {
error("Expected '{' for function statement");
continue;
}
// 1. Function name
std::string name = line.substr(3, block_start - 3);
function_inst.args.push_back(Value(Instruction(split(trim(name)))));
// 2. Find 'then' block
size_t block_end = 0;
int brace_level = 0;
for (size_t i = block_start; i < line.length(); ++i) {
if (line[i] == '{') brace_level++;
else if (line[i] == '}') brace_level--;
if (brace_level == 0) {
block_end = i;
break;
}
}
if (block_end == 0) {
error("Mismatched braces in function statement");
continue;
}
std::string then_content = line.substr(block_start + 1, block_end - block_start - 1);
function_inst.args.push_back(Value(parse(then_content))); // Recursive call
instructions.push_back(function_inst);
} else {
instructions.push_back(Instruction(split(line)));
}
}
return instructions;
}
}

5
tests/func.kyn Normal file
View File

@@ -0,0 +1,5 @@
fun dingus {
println "hello"
}
dingus

6
tests/loop.kyn Normal file
View File

@@ -0,0 +1,6 @@
let counter = 0
while compare $counter <= 1000 {
println $counter
counter = (math 1 + $counter)
}