feat: Symmetric Multiprocessing, text editor improvements, merge doom libc, implement math functions

This commit is contained in:
2026-03-23 20:09:11 +01:00
parent a805b06406
commit 63d9270613
46 changed files with 3004 additions and 2404 deletions
@@ -1076,8 +1076,8 @@ static void filemanager_open_entry(FileManagerState* fm, int idx) {
montauk::spawn("0:/apps/music/music.elf", fullpath);
} else if (str_ends_with(fm->entry_names[idx], ".elf")) {
montauk::spawn(fullpath);
} else if (fm->desktop) {
open_texteditor_with_file(fm->desktop, fullpath);
} else {
montauk::spawn("0:/apps/texteditor/texteditor.elf", fullpath);
}
}
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -20,6 +20,7 @@ endif
DOOM_SRC := ../../../doomgeneric/doomgeneric
LIBC_INC := ../../include/libc
PROG_INC := ../../include
LIBDIR := ../../lib
LINK_LD := ../../link.ld
BINDIR := ../../bin
OBJDIR := obj
@@ -153,7 +154,7 @@ DOOM_SRCS := \
z_zone.c
# Local source files
LOCAL_SRCS := doomgeneric_montauk.c libc.c
LOCAL_SRCS := doomgeneric_montauk.c
# ---- Object files ----
@@ -171,7 +172,7 @@ all: $(TARGET)
$(TARGET): $(ALL_OBJS) $(LINK_LD) Makefile
mkdir -p $(BINDIR)/apps/doom
$(LD) $(CFLAGS) $(LDFLAGS) $(ALL_OBJS) -o $@
$(LD) $(CFLAGS) $(LDFLAGS) $(ALL_OBJS) $(LIBDIR)/libc/liblibc.a -o $@
# DOOM source files (from doomgeneric directory)
$(OBJDIR)/%.o: $(DOOM_SRC)/%.c Makefile
File diff suppressed because it is too large Load Diff
+86
View File
@@ -0,0 +1,86 @@
# Makefile for texteditor (standalone Window Server app) on MontaukOS
# Copyright (c) 2026 Daniel Hammer
MAKEFLAGS += -rR
.SUFFIXES:
# ---- Toolchain ----
TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-elf-
ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),)
CXX := $(TOOLCHAIN_PREFIX)g++
else
CXX := g++
endif
# ---- Paths ----
PROG_INC := ../../include
LINK_LD := ../../link.ld
BINDIR := ../../bin
OBJDIR := obj
LIBDIR := ../../lib
# ---- Compiler flags ----
CXXFLAGS := \
-std=gnu++20 \
-g -O2 -pipe \
-Wall \
-Wextra \
-Wno-unused-parameter \
-Wno-unused-function \
-nostdinc \
-ffreestanding \
-fno-stack-protector \
-fno-stack-check \
-fno-PIC \
-fno-rtti \
-fno-exceptions \
-ffunction-sections \
-fdata-sections \
-m64 \
-march=x86-64 \
-msse \
-msse2 \
-mno-red-zone \
-mcmodel=small \
-I $(PROG_INC) \
-isystem $(PROG_INC)/libc \
-isystem ../../../kernel/freestnd-c-hdrs/x86_64/include \
-isystem ../../../kernel/freestnd-cxx-hdrs/x86_64/include
# ---- Linker flags ----
LDFLAGS := \
-nostdlib \
-static \
-Wl,--build-id=none \
-Wl,--gc-sections \
-Wl,-m,elf_x86_64 \
-z max-page-size=0x1000 \
-T $(LINK_LD)
# ---- Source files ----
SRCS := main.cpp stb_truetype_impl.cpp
OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o))
# ---- Target ----
TARGET := $(BINDIR)/apps/texteditor/texteditor.elf
.PHONY: all clean
all: $(TARGET)
$(TARGET): $(OBJS) $(LINK_LD) Makefile
mkdir -p $(BINDIR)/apps/texteditor
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@
$(OBJDIR)/%.o: %.cpp Makefile
mkdir -p $(OBJDIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -rf $(OBJDIR) $(TARGET)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
/*
* stb_truetype_impl.cpp
* Single compilation unit for stb_truetype in MontaukOS freestanding environment
* Copyright (c) 2026 Daniel Hammer
*/
#include <cstdint>
#include <cstddef>
#include <montauk/heap.h>
#include <montauk/string.h>
#include <gui/stb_math.h>
// Override all stb_truetype dependencies before including the implementation
#define STBTT_ifloor(x) ((int) stb_floor(x))
#define STBTT_iceil(x) ((int) stb_ceil(x))
#define STBTT_sqrt(x) stb_sqrt(x)
#define STBTT_pow(x,y) stb_pow(x,y)
#define STBTT_fmod(x,y) stb_fmod(x,y)
#define STBTT_cos(x) stb_cos(x)
#define STBTT_acos(x) stb_acos(x)
#define STBTT_fabs(x) stb_fabs(x)
#define STBTT_malloc(x,u) ((void)(u), montauk::malloc(x))
#define STBTT_free(x,u) ((void)(u), montauk::mfree(x))
#define STBTT_memcpy(d,s,n) montauk::memcpy(d,s,n)
#define STBTT_memset(d,v,n) montauk::memset(d,v,n)
#define STBTT_strlen(x) montauk::slen(x)
#define STBTT_assert(x) ((void)(x))
#define STB_TRUETYPE_IMPLEMENTATION
#include <gui/stb_truetype.h>
@@ -0,0 +1,287 @@
/*
* syntax_highlight.hpp
* C syntax highlighting for the MontaukOS text editor
* Activated for .c and .h files
* Copyright (c) 2026 Daniel Hammer
*/
#pragma once
#include <gui/gui.hpp>
using namespace gui;
// ============================================================================
// Token types
// ============================================================================
enum SynToken : uint8_t {
SYN_NORMAL,
SYN_KEYWORD,
SYN_TYPE,
SYN_PREPROCESSOR,
SYN_STRING,
SYN_CHAR,
SYN_COMMENT,
SYN_NUMBER,
SYN_OPERATOR,
};
// ============================================================================
// Colors for each token type
// ============================================================================
inline Color syn_color(SynToken tok) {
switch (tok) {
case SYN_KEYWORD: return Color::from_rgb(0xC5, 0x62, 0x8C); // magenta-pink
case SYN_TYPE: return Color::from_rgb(0x2E, 0x86, 0xAB); // teal
case SYN_PREPROCESSOR: return Color::from_rgb(0x8B, 0x6E, 0xB5); // purple
case SYN_STRING: return Color::from_rgb(0x6A, 0x9F, 0x3A); // green
case SYN_CHAR: return Color::from_rgb(0x6A, 0x9F, 0x3A); // green
case SYN_COMMENT: return Color::from_rgb(0x7A, 0x7A, 0x7A); // gray
case SYN_NUMBER: return Color::from_rgb(0xC9, 0x7E, 0x2A); // orange
case SYN_OPERATOR: return Color::from_rgb(0x40, 0x40, 0x40); // dark gray
default: return Color::from_rgb(0x1E, 0x1E, 0x1E); // near-black
}
}
// ============================================================================
// Keyword / type lookup
// ============================================================================
inline bool syn_is_alpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
inline bool syn_is_alnum(char c) {
return syn_is_alpha(c) || (c >= '0' && c <= '9');
}
inline bool syn_is_digit(char c) {
return c >= '0' && c <= '9';
}
inline bool syn_is_hex(char c) {
return syn_is_digit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
inline bool syn_streq(const char* buf, int len, const char* kw) {
int i = 0;
while (i < len && kw[i]) {
if (buf[i] != kw[i]) return false;
i++;
}
return i == len && kw[i] == '\0';
}
inline SynToken syn_classify_word(const char* buf, int len) {
// C keywords
static const char* keywords[] = {
"auto", "break", "case", "const", "continue", "default", "do",
"else", "enum", "extern", "for", "goto", "if", "inline",
"register", "restrict", "return", "sizeof", "static", "struct",
"switch", "typedef", "union", "volatile", "while",
"NULL", "true", "false", "nullptr",
};
// C types
static const char* types[] = {
"void", "char", "short", "int", "long", "float", "double",
"signed", "unsigned", "bool", "_Bool",
"int8_t", "int16_t", "int32_t", "int64_t",
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
"size_t", "ssize_t", "ptrdiff_t", "intptr_t", "uintptr_t",
"FILE",
};
for (int i = 0; i < (int)(sizeof(keywords) / sizeof(keywords[0])); i++) {
if (syn_streq(buf, len, keywords[i])) return SYN_KEYWORD;
}
for (int i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++) {
if (syn_streq(buf, len, types[i])) return SYN_TYPE;
}
return SYN_NORMAL;
}
// ============================================================================
// Per-line highlighter
// ============================================================================
//
// Fills `out[]` with SynToken values for each character in the line.
// `in_block_comment` is the multi-line comment state carried across lines:
// - pass in the state from the previous line
// - on return, updated for the next line
//
// `line` points to the first char of the line, `len` is its length
// (excluding the newline). `out` must have room for `len` entries.
inline void syn_highlight_line(const char* line, int len, SynToken* out, bool& in_block_comment) {
int i = 0;
while (i < len) {
// ---- Block comment continuation ----
if (in_block_comment) {
while (i < len) {
if (i + 1 < len && line[i] == '*' && line[i + 1] == '/') {
out[i] = SYN_COMMENT;
out[i + 1] = SYN_COMMENT;
i += 2;
in_block_comment = false;
break;
}
out[i] = SYN_COMMENT;
i++;
}
continue;
}
char c = line[i];
// ---- Line comment ----
if (c == '/' && i + 1 < len && line[i + 1] == '/') {
while (i < len) out[i++] = SYN_COMMENT;
break;
}
// ---- Block comment start ----
if (c == '/' && i + 1 < len && line[i + 1] == '*') {
in_block_comment = true;
out[i] = SYN_COMMENT;
out[i + 1] = SYN_COMMENT;
i += 2;
continue;
}
// ---- Preprocessor directive ----
if (c == '#') {
// Check that only whitespace precedes the #
bool is_pp = true;
for (int j = 0; j < i; j++) {
if (line[j] != ' ' && line[j] != '\t') { is_pp = false; break; }
}
if (is_pp) {
while (i < len) {
// Handle line-comment inside preprocessor
if (i + 1 < len && line[i] == '/' && line[i + 1] == '/') {
while (i < len) out[i++] = SYN_COMMENT;
break;
}
// Handle block comment start inside preprocessor
if (i + 1 < len && line[i] == '/' && line[i + 1] == '*') {
in_block_comment = true;
out[i] = SYN_COMMENT;
out[i + 1] = SYN_COMMENT;
i += 2;
// Continue consuming as comment
while (i < len) {
if (i + 1 < len && line[i] == '*' && line[i + 1] == '/') {
out[i] = SYN_COMMENT;
out[i + 1] = SYN_COMMENT;
i += 2;
in_block_comment = false;
break;
}
out[i] = SYN_COMMENT;
i++;
}
continue;
}
out[i] = SYN_PREPROCESSOR;
i++;
}
continue;
}
}
// ---- String literal ----
if (c == '"') {
out[i++] = SYN_STRING;
while (i < len) {
if (line[i] == '\\' && i + 1 < len) {
out[i] = SYN_STRING;
out[i + 1] = SYN_STRING;
i += 2;
continue;
}
if (line[i] == '"') {
out[i++] = SYN_STRING;
break;
}
out[i++] = SYN_STRING;
}
continue;
}
// ---- Character literal ----
if (c == '\'') {
out[i++] = SYN_CHAR;
while (i < len) {
if (line[i] == '\\' && i + 1 < len) {
out[i] = SYN_CHAR;
out[i + 1] = SYN_CHAR;
i += 2;
continue;
}
if (line[i] == '\'') {
out[i++] = SYN_CHAR;
break;
}
out[i++] = SYN_CHAR;
}
continue;
}
// ---- Numbers ----
if (syn_is_digit(c) || (c == '.' && i + 1 < len && syn_is_digit(line[i + 1]))) {
// Hex
if (c == '0' && i + 1 < len && (line[i + 1] == 'x' || line[i + 1] == 'X')) {
out[i] = SYN_NUMBER; out[i + 1] = SYN_NUMBER;
i += 2;
while (i < len && syn_is_hex(line[i])) out[i++] = SYN_NUMBER;
} else {
// Decimal / float
while (i < len && (syn_is_digit(line[i]) || line[i] == '.'))
out[i++] = SYN_NUMBER;
}
// Suffixes: u, l, f, etc.
while (i < len && (line[i] == 'u' || line[i] == 'U' ||
line[i] == 'l' || line[i] == 'L' ||
line[i] == 'f' || line[i] == 'F'))
out[i++] = SYN_NUMBER;
continue;
}
// ---- Identifiers / keywords / types ----
if (syn_is_alpha(c)) {
int start = i;
while (i < len && syn_is_alnum(line[i])) i++;
SynToken tok = syn_classify_word(line + start, i - start);
for (int j = start; j < i; j++) out[j] = tok;
continue;
}
// ---- Operators ----
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '%' ||
c == '=' || c == '!' || c == '<' || c == '>' || c == '&' ||
c == '|' || c == '^' || c == '~' || c == '?' || c == ':') {
out[i++] = SYN_OPERATOR;
continue;
}
// ---- Everything else (whitespace, braces, parens, etc.) ----
out[i++] = SYN_NORMAL;
}
}
// ============================================================================
// Extension check
// ============================================================================
inline bool syn_is_c_file(const char* filepath) {
if (!filepath || filepath[0] == '\0') return false;
int len = 0;
while (filepath[len]) len++;
if (len >= 2 && filepath[len - 2] == '.' &&
(filepath[len - 1] == 'c' || filepath[len - 1] == 'h'))
return true;
return false;
}