2026-05-03 21:45:29 +03:00
|
|
|
#
|
|
|
|
|
# Blaise — An Object Pascal Compiler
|
|
|
|
|
# Copyright (c) 2026 Graeme Geldenhuys
|
|
|
|
|
# SPDX-License-Identifier: Apache-2.0 WITH Swift-exception
|
|
|
|
|
# Licensed under the Apache License v2.0 with Runtime Library Exception.
|
|
|
|
|
# See LICENSE file in the project root for full license terms.
|
|
|
|
|
#
|
Add Phase 2: record/class types, ARC strings, RTL stubs, and grammar doc
Symbol table:
- Added tyClass kind and NewClassType factory; TRecordTypeDesc now
accepts an optional kind parameter so records and classes share the
same descriptor with distinct semantics.
Semantic analyser:
- AnalyseTypeDecls runs before PushScope so type symbols land in global
scope and survive PopScope.
- Handles TRecordTypeDef and TClassTypeDef; sets IsConstructorCall on
TypeName.Create expressions and IsClassAccess on class-variable field
access and assignment nodes.
Code generator (QBE IR):
- Class variables: 8-byte pointer slot, zeroed on entry.
- Constructor calls: malloc(sizeof fields), store pointer.
- Class field access/write: load pointer, add field offset, load/store.
- ARC string assignment: AddRef new value, Release old value, then store.
- Block exit: Release every string variable in scope (EmitStringCleanup).
Lexer / Parser / AST:
- Added tkClass keyword and ParseClassDef; FieldDecl parsing refactored
into ParseFieldDecl(AFields) shared by both record and class.
- AST gains TClassTypeDef, and IsConstructorCall/IsClassAccess flags on
TFieldAccessExpr and TFieldAssignment.
RTL:
- blaise_arc.c: Phase 2 no-op stubs for _StringAddRef / _StringRelease.
- rtl/Makefile: builds blaise_rtl.a; `make install` copies it next to
the compiler binary for automatic discovery by FindRTL.
- Blaise.pas driver: FindRTL checks BLAISE_RTL env var then binary dir;
links the RTL archive when present.
Tests:
- 180 unit tests (records ×23, classes ×22, ARC ×9, codegen ×9, …).
- 4 end-to-end integration tests in tests/integration/test_arc_strings.sh
covering string assignment, two-var cleanup, reassignment cycle, and
empty-program linkage.
Docs:
- design.adoc updated with Phase 2 implementation status table.
- docs/grammar.ebnf: new authoritative EBNF grammar for the Blaise
language as implemented, including ARC semantic annotations.
2026-04-20 21:04:12 +03:00
|
|
|
CC = gcc
|
|
|
|
|
CFLAGS = -O2 -Wall -Wextra -std=c11
|
|
|
|
|
|
2026-05-01 16:42:29 +03:00
|
|
|
SRC_DIR = src/main/c
|
|
|
|
|
PAS_SRC_DIR = src/main/pascal
|
|
|
|
|
OBJ_DIR = target
|
|
|
|
|
LIB = $(OBJ_DIR)/blaise_rtl.a
|
Add Phase 2: record/class types, ARC strings, RTL stubs, and grammar doc
Symbol table:
- Added tyClass kind and NewClassType factory; TRecordTypeDesc now
accepts an optional kind parameter so records and classes share the
same descriptor with distinct semantics.
Semantic analyser:
- AnalyseTypeDecls runs before PushScope so type symbols land in global
scope and survive PopScope.
- Handles TRecordTypeDef and TClassTypeDef; sets IsConstructorCall on
TypeName.Create expressions and IsClassAccess on class-variable field
access and assignment nodes.
Code generator (QBE IR):
- Class variables: 8-byte pointer slot, zeroed on entry.
- Constructor calls: malloc(sizeof fields), store pointer.
- Class field access/write: load pointer, add field offset, load/store.
- ARC string assignment: AddRef new value, Release old value, then store.
- Block exit: Release every string variable in scope (EmitStringCleanup).
Lexer / Parser / AST:
- Added tkClass keyword and ParseClassDef; FieldDecl parsing refactored
into ParseFieldDecl(AFields) shared by both record and class.
- AST gains TClassTypeDef, and IsConstructorCall/IsClassAccess flags on
TFieldAccessExpr and TFieldAssignment.
RTL:
- blaise_arc.c: Phase 2 no-op stubs for _StringAddRef / _StringRelease.
- rtl/Makefile: builds blaise_rtl.a; `make install` copies it next to
the compiler binary for automatic discovery by FindRTL.
- Blaise.pas driver: FindRTL checks BLAISE_RTL env var then binary dir;
links the RTL archive when present.
Tests:
- 180 unit tests (records ×23, classes ×22, ARC ×9, codegen ×9, …).
- 4 end-to-end integration tests in tests/integration/test_arc_strings.sh
covering string assignment, two-var cleanup, reassignment cycle, and
empty-program linkage.
Docs:
- design.adoc updated with Phase 2 implementation status table.
- docs/grammar.ebnf: new authoritative EBNF grammar for the Blaise
language as implemented, including ARC semantic annotations.
2026-04-20 21:04:12 +03:00
|
|
|
|
|
|
|
|
# Where the compiler binary lives — install copies the RTL there so the
|
|
|
|
|
# driver finds it automatically next to itself.
|
2026-04-24 19:42:54 +03:00
|
|
|
COMPILER_BIN = ../compiler/target
|
2026-05-01 16:42:29 +03:00
|
|
|
BLAISE = $(COMPILER_BIN)/blaise
|
|
|
|
|
QBE = ../vendor/qbe/qbe
|
Add Phase 2: record/class types, ARC strings, RTL stubs, and grammar doc
Symbol table:
- Added tyClass kind and NewClassType factory; TRecordTypeDesc now
accepts an optional kind parameter so records and classes share the
same descriptor with distinct semantics.
Semantic analyser:
- AnalyseTypeDecls runs before PushScope so type symbols land in global
scope and survive PopScope.
- Handles TRecordTypeDef and TClassTypeDef; sets IsConstructorCall on
TypeName.Create expressions and IsClassAccess on class-variable field
access and assignment nodes.
Code generator (QBE IR):
- Class variables: 8-byte pointer slot, zeroed on entry.
- Constructor calls: malloc(sizeof fields), store pointer.
- Class field access/write: load pointer, add field offset, load/store.
- ARC string assignment: AddRef new value, Release old value, then store.
- Block exit: Release every string variable in scope (EmitStringCleanup).
Lexer / Parser / AST:
- Added tkClass keyword and ParseClassDef; FieldDecl parsing refactored
into ParseFieldDecl(AFields) shared by both record and class.
- AST gains TClassTypeDef, and IsConstructorCall/IsClassAccess flags on
TFieldAccessExpr and TFieldAssignment.
RTL:
- blaise_arc.c: Phase 2 no-op stubs for _StringAddRef / _StringRelease.
- rtl/Makefile: builds blaise_rtl.a; `make install` copies it next to
the compiler binary for automatic discovery by FindRTL.
- Blaise.pas driver: FindRTL checks BLAISE_RTL env var then binary dir;
links the RTL archive when present.
Tests:
- 180 unit tests (records ×23, classes ×22, ARC ×9, codegen ×9, …).
- 4 end-to-end integration tests in tests/integration/test_arc_strings.sh
covering string assignment, two-var cleanup, reassignment cycle, and
empty-program linkage.
Docs:
- design.adoc updated with Phase 2 implementation status table.
- docs/grammar.ebnf: new authoritative EBNF grammar for the Blaise
language as implemented, including ARC semantic annotations.
2026-04-20 21:04:12 +03:00
|
|
|
|
2026-05-01 16:42:29 +03:00
|
|
|
# C sources (blaise_str.pas replaces blaise_str.c; blaise_str_fmt.c keeps
|
|
|
|
|
# the variadic _StringFormat which cannot be expressed in Pascal).
|
2026-05-01 18:26:17 +03:00
|
|
|
C_SRCS = $(SRC_DIR)/blaise_arc_class.c \
|
2026-05-01 16:42:29 +03:00
|
|
|
$(SRC_DIR)/blaise_exc.c \
|
|
|
|
|
$(SRC_DIR)/blaise_weak.c \
|
|
|
|
|
$(SRC_DIR)/blaise_str_fmt.c \
|
|
|
|
|
$(SRC_DIR)/blaise_io.c \
|
2026-05-01 19:22:07 +03:00
|
|
|
$(SRC_DIR)/blaise_process.c \
|
|
|
|
|
$(SRC_DIR)/blaise_sys_posix.c
|
2026-05-01 16:42:29 +03:00
|
|
|
C_OBJS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS))
|
|
|
|
|
|
|
|
|
|
# Pascal RTL units compiled via the Blaise compiler.
|
|
|
|
|
# Each unit is compiled by a thin driver program; the program section is
|
|
|
|
|
# stripped from the IR so only the unit's exported functions are archived.
|
2026-05-01 18:26:17 +03:00
|
|
|
PAS_OBJS = $(OBJ_DIR)/blaise_str.o \
|
2026-05-01 19:22:07 +03:00
|
|
|
$(OBJ_DIR)/blaise_arc.o \
|
|
|
|
|
$(OBJ_DIR)/blaise_sys.o
|
2026-05-01 16:42:29 +03:00
|
|
|
|
|
|
|
|
OBJS = $(C_OBJS) $(PAS_OBJS)
|
Add Phase 2: record/class types, ARC strings, RTL stubs, and grammar doc
Symbol table:
- Added tyClass kind and NewClassType factory; TRecordTypeDesc now
accepts an optional kind parameter so records and classes share the
same descriptor with distinct semantics.
Semantic analyser:
- AnalyseTypeDecls runs before PushScope so type symbols land in global
scope and survive PopScope.
- Handles TRecordTypeDef and TClassTypeDef; sets IsConstructorCall on
TypeName.Create expressions and IsClassAccess on class-variable field
access and assignment nodes.
Code generator (QBE IR):
- Class variables: 8-byte pointer slot, zeroed on entry.
- Constructor calls: malloc(sizeof fields), store pointer.
- Class field access/write: load pointer, add field offset, load/store.
- ARC string assignment: AddRef new value, Release old value, then store.
- Block exit: Release every string variable in scope (EmitStringCleanup).
Lexer / Parser / AST:
- Added tkClass keyword and ParseClassDef; FieldDecl parsing refactored
into ParseFieldDecl(AFields) shared by both record and class.
- AST gains TClassTypeDef, and IsConstructorCall/IsClassAccess flags on
TFieldAccessExpr and TFieldAssignment.
RTL:
- blaise_arc.c: Phase 2 no-op stubs for _StringAddRef / _StringRelease.
- rtl/Makefile: builds blaise_rtl.a; `make install` copies it next to
the compiler binary for automatic discovery by FindRTL.
- Blaise.pas driver: FindRTL checks BLAISE_RTL env var then binary dir;
links the RTL archive when present.
Tests:
- 180 unit tests (records ×23, classes ×22, ARC ×9, codegen ×9, …).
- 4 end-to-end integration tests in tests/integration/test_arc_strings.sh
covering string assignment, two-var cleanup, reassignment cycle, and
empty-program linkage.
Docs:
- design.adoc updated with Phase 2 implementation status table.
- docs/grammar.ebnf: new authoritative EBNF grammar for the Blaise
language as implemented, including ARC semantic annotations.
2026-04-20 21:04:12 +03:00
|
|
|
|
|
|
|
|
.PHONY: all install clean
|
|
|
|
|
|
|
|
|
|
all: $(LIB)
|
|
|
|
|
|
|
|
|
|
$(LIB): $(OBJS)
|
|
|
|
|
ar rcs $@ $^
|
|
|
|
|
|
2026-05-01 16:42:29 +03:00
|
|
|
# --- C rules ---
|
Add Phase 2: record/class types, ARC strings, RTL stubs, and grammar doc
Symbol table:
- Added tyClass kind and NewClassType factory; TRecordTypeDesc now
accepts an optional kind parameter so records and classes share the
same descriptor with distinct semantics.
Semantic analyser:
- AnalyseTypeDecls runs before PushScope so type symbols land in global
scope and survive PopScope.
- Handles TRecordTypeDef and TClassTypeDef; sets IsConstructorCall on
TypeName.Create expressions and IsClassAccess on class-variable field
access and assignment nodes.
Code generator (QBE IR):
- Class variables: 8-byte pointer slot, zeroed on entry.
- Constructor calls: malloc(sizeof fields), store pointer.
- Class field access/write: load pointer, add field offset, load/store.
- ARC string assignment: AddRef new value, Release old value, then store.
- Block exit: Release every string variable in scope (EmitStringCleanup).
Lexer / Parser / AST:
- Added tkClass keyword and ParseClassDef; FieldDecl parsing refactored
into ParseFieldDecl(AFields) shared by both record and class.
- AST gains TClassTypeDef, and IsConstructorCall/IsClassAccess flags on
TFieldAccessExpr and TFieldAssignment.
RTL:
- blaise_arc.c: Phase 2 no-op stubs for _StringAddRef / _StringRelease.
- rtl/Makefile: builds blaise_rtl.a; `make install` copies it next to
the compiler binary for automatic discovery by FindRTL.
- Blaise.pas driver: FindRTL checks BLAISE_RTL env var then binary dir;
links the RTL archive when present.
Tests:
- 180 unit tests (records ×23, classes ×22, ARC ×9, codegen ×9, …).
- 4 end-to-end integration tests in tests/integration/test_arc_strings.sh
covering string assignment, two-var cleanup, reassignment cycle, and
empty-program linkage.
Docs:
- design.adoc updated with Phase 2 implementation status table.
- docs/grammar.ebnf: new authoritative EBNF grammar for the Blaise
language as implemented, including ARC semantic annotations.
2026-04-20 21:04:12 +03:00
|
|
|
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
|
|
|
|
@mkdir -p $(OBJ_DIR)
|
|
|
|
|
$(CC) $(CFLAGS) -c -o $@ $<
|
|
|
|
|
|
2026-05-01 16:42:29 +03:00
|
|
|
# --- Pascal unit rules ---
|
|
|
|
|
# Compile via a build driver, strip everything from '# Generated by Blaise'
|
|
|
|
|
# onward (the program section), assemble the unit-only IR, then compile to .o.
|
|
|
|
|
$(OBJ_DIR)/blaise_str.ssa: $(PAS_SRC_DIR)/blaise_str.pas \
|
|
|
|
|
$(PAS_SRC_DIR)/blaise_str_build_driver.pas
|
|
|
|
|
@mkdir -p $(OBJ_DIR)
|
|
|
|
|
$(BLAISE) --source $(PAS_SRC_DIR)/blaise_str_build_driver.pas \
|
|
|
|
|
--unit-path $(PAS_SRC_DIR) \
|
|
|
|
|
--emit-ir \
|
|
|
|
|
| sed '/^# Generated by Blaise/,$$d' > $@
|
|
|
|
|
|
|
|
|
|
$(OBJ_DIR)/blaise_str.s: $(OBJ_DIR)/blaise_str.ssa
|
|
|
|
|
$(QBE) -o $@ $<
|
|
|
|
|
|
|
|
|
|
$(OBJ_DIR)/blaise_str.o: $(OBJ_DIR)/blaise_str.s
|
|
|
|
|
$(CC) -c -o $@ $<
|
|
|
|
|
|
2026-05-01 18:26:17 +03:00
|
|
|
$(OBJ_DIR)/blaise_arc.ssa: $(PAS_SRC_DIR)/blaise_arc.pas \
|
|
|
|
|
$(PAS_SRC_DIR)/blaise_arc_build_driver.pas
|
|
|
|
|
@mkdir -p $(OBJ_DIR)
|
|
|
|
|
$(BLAISE) --source $(PAS_SRC_DIR)/blaise_arc_build_driver.pas \
|
|
|
|
|
--unit-path $(PAS_SRC_DIR) \
|
|
|
|
|
--emit-ir \
|
|
|
|
|
| sed '/^# Generated by Blaise/,$$d' > $@
|
|
|
|
|
|
|
|
|
|
$(OBJ_DIR)/blaise_arc.s: $(OBJ_DIR)/blaise_arc.ssa
|
|
|
|
|
$(QBE) -o $@ $<
|
|
|
|
|
|
|
|
|
|
$(OBJ_DIR)/blaise_arc.o: $(OBJ_DIR)/blaise_arc.s
|
|
|
|
|
$(CC) -c -o $@ $<
|
|
|
|
|
|
2026-05-01 19:22:07 +03:00
|
|
|
$(OBJ_DIR)/blaise_sys.ssa: $(PAS_SRC_DIR)/blaise_sys.pas \
|
|
|
|
|
$(PAS_SRC_DIR)/blaise_sys_build_driver.pas
|
|
|
|
|
@mkdir -p $(OBJ_DIR)
|
|
|
|
|
$(BLAISE) --source $(PAS_SRC_DIR)/blaise_sys_build_driver.pas \
|
|
|
|
|
--unit-path $(PAS_SRC_DIR) \
|
|
|
|
|
--emit-ir \
|
|
|
|
|
| sed '/^# Generated by Blaise/,$$d' > $@
|
|
|
|
|
|
|
|
|
|
$(OBJ_DIR)/blaise_sys.s: $(OBJ_DIR)/blaise_sys.ssa
|
|
|
|
|
$(QBE) -o $@ $<
|
|
|
|
|
|
|
|
|
|
$(OBJ_DIR)/blaise_sys.o: $(OBJ_DIR)/blaise_sys.s
|
|
|
|
|
$(CC) -c -o $@ $<
|
|
|
|
|
|
Add Phase 2: record/class types, ARC strings, RTL stubs, and grammar doc
Symbol table:
- Added tyClass kind and NewClassType factory; TRecordTypeDesc now
accepts an optional kind parameter so records and classes share the
same descriptor with distinct semantics.
Semantic analyser:
- AnalyseTypeDecls runs before PushScope so type symbols land in global
scope and survive PopScope.
- Handles TRecordTypeDef and TClassTypeDef; sets IsConstructorCall on
TypeName.Create expressions and IsClassAccess on class-variable field
access and assignment nodes.
Code generator (QBE IR):
- Class variables: 8-byte pointer slot, zeroed on entry.
- Constructor calls: malloc(sizeof fields), store pointer.
- Class field access/write: load pointer, add field offset, load/store.
- ARC string assignment: AddRef new value, Release old value, then store.
- Block exit: Release every string variable in scope (EmitStringCleanup).
Lexer / Parser / AST:
- Added tkClass keyword and ParseClassDef; FieldDecl parsing refactored
into ParseFieldDecl(AFields) shared by both record and class.
- AST gains TClassTypeDef, and IsConstructorCall/IsClassAccess flags on
TFieldAccessExpr and TFieldAssignment.
RTL:
- blaise_arc.c: Phase 2 no-op stubs for _StringAddRef / _StringRelease.
- rtl/Makefile: builds blaise_rtl.a; `make install` copies it next to
the compiler binary for automatic discovery by FindRTL.
- Blaise.pas driver: FindRTL checks BLAISE_RTL env var then binary dir;
links the RTL archive when present.
Tests:
- 180 unit tests (records ×23, classes ×22, ARC ×9, codegen ×9, …).
- 4 end-to-end integration tests in tests/integration/test_arc_strings.sh
covering string assignment, two-var cleanup, reassignment cycle, and
empty-program linkage.
Docs:
- design.adoc updated with Phase 2 implementation status table.
- docs/grammar.ebnf: new authoritative EBNF grammar for the Blaise
language as implemented, including ARC semantic annotations.
2026-04-20 21:04:12 +03:00
|
|
|
install: $(LIB)
|
|
|
|
|
@mkdir -p $(COMPILER_BIN)
|
|
|
|
|
cp $(LIB) $(COMPILER_BIN)/blaise_rtl.a
|
|
|
|
|
@echo "Installed blaise_rtl.a → $(COMPILER_BIN)/blaise_rtl.a"
|
|
|
|
|
|
|
|
|
|
clean:
|
2026-05-01 16:42:29 +03:00
|
|
|
rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.s $(OBJ_DIR)/*.ssa $(LIB)
|