Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3f25169
[docs] extract coding style rules into CODING_STYLE.md
melkyades Apr 4, 2026
6542bd8
[docs] update git commit labelling format in documentation
melkyades Apr 4, 2026
7787bc0
[kernel] fix property tables
melkyades Apr 7, 2026
c98745c
[kernel] refactor ReadStream peek methods for clarity and consistency
melkyades Apr 7, 2026
89129bd
[sunit] add TestSuite>>runDebug for log-as-you-go runs
melkyades Apr 22, 2026
27bf51d
[argparser] add ArgParser module: parser, commands, options, results
melkyades Apr 22, 2026
4a7c36c
[epm] add EPMModule with `test` command
melkyades Apr 22, 2026
6922032
[random] add Random module (PCG XSH-RR PRNG)
melkyades Apr 22, 2026
1bd3b5c
[tonel] fix block reader, sort methods, write class comment, and add …
melkyades Apr 22, 2026
4076bb4
[sunit] add TestSuite class>>forModule:
melkyades Apr 28, 2026
8f48d6b
[bare-tests] add bitwise/shift tests and runnable main:
melkyades Apr 29, 2026
8956c90
[vm] SmallInteger arithmetic & bitwise overflow fallback
melkyades Apr 29, 2026
81be103
[bare-tests] add test182BitShiftRightFullWidth regression
melkyades Apr 29, 2026
216dd4a
[vm/float] fix Float>>timesTwoPower: primitive
melkyades Apr 29, 2026
caa6666
[kernel] WideSymbol class>>intern: operate on argument, not receiver
melkyades Apr 30, 2026
0263685
[kernel] add ProtoObject _uLongAtOffset: / _uLongAtValidOffset:put:
melkyades May 1, 2026
120d6b1
[compiler] LargeInteger as little-endian bytes; parser cleanup; boots…
melkyades May 1, 2026
fc09804
[compiler/tests] add Compiler.Tests module with SmalltalkScanner tests
melkyades May 1, 2026
b82291d
[bootstrap] extract MethodDictBuilder abstraction
melkyades May 1, 2026
b768f88
[bootstrap/tonel] support Extension type, comments, method category, …
melkyades May 1, 2026
62f332d
[build] default Debug builds to -O1 for usable VM speed
melkyades May 1, 2026
fdeaf4a
[kernel/host] add filesystem & env primitives, search-path module loa…
melkyades May 2, 2026
7f6ac96
[loader] support dotted module names and load-from-path
melkyades May 2, 2026
4579a94
[modules/toml] add TOML module with parser, writer and tests
melkyades May 2, 2026
e7388a8
[modules/epm] config-driven workflows: new/init/start/dev/install/list
melkyades May 2, 2026
3fe76c5
[runtime/allocator] fix commitMemoryUpTo_ length calculation
melkyades May 2, 2026
8538e26
[runtime] GC-protect DynamicSymbolProvider symbol table
melkyades May 2, 2026
227d138
[runtime] small fixes: debugRuntime, Character, loadModuleFromPath_
melkyades May 2, 2026
9d7faf3
[runtime/primitive] fix StringReplaceFromToWithStartingAt bounds
melkyades May 3, 2026
26c34f6
[compiler/inliner] do not inline any cascade message
melkyades May 3, 2026
3c796d6
[runtime/bootstrap] add Catch2 tests for parser, source loader and co…
melkyades May 3, 2026
cee0943
[chore] drop committed .vscode/settings.json
melkyades May 4, 2026
8232903
[runtime/build] migrate conanfile.txt to conanfile.py
melkyades May 4, 2026
cf124ee
[docs] expand contributor docs (style guides + runtime READMEs)
melkyades May 4, 2026
c160ddd
[runtime/build] drop -s compiler.cppstd=20 from Makefile conan install
melkyades May 4, 2026
4430943
[runtime/evaluator] warn instead of aborting on missing primitive
melkyades May 4, 2026
4f66a94
[modules/ston] initialize STONWriter on module load
melkyades May 4, 2026
aac20ee
[chore] ignore build dirs and .vscode/settings.json
melkyades May 4, 2026
30d3dee
[runtime/build] link bootstrapper_lib into compiler_tests
melkyades May 4, 2026
cb57a76
[runtime/build] declare egg_runtime <-> bootstrapper_lib cycle
melkyades May 4, 2026
02a388d
[vm][pharo] implement missing host primitives
melkyades May 4, 2026
9de1f10
[vm] portable intptr_t mul-overflow helper for MSVC
melkyades May 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.DS_Store
release/*
build
runtime/cpp/build-*
.vscode/settings.json
7 changes: 0 additions & 7 deletions .vscode/settings.json

This file was deleted.

270 changes: 270 additions & 0 deletions CODING_STYLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
# Coding Style

This document describes the coding style rules for egg. All code is expected to
strictly follow them to maintain the homogeneity of the codebase.

## General Philosophy

We spend most of our time reading existing code. For that reason we aim to minimize
the amount of text to be read. Shorter code means less effort and more things fitting
on screen.

- Favor simplicity and minimality over performance.
- Leave simple optimizations to the runtime system instead of writing them by hand.
- All code is autoformatted, unless there is a _very_ special and specific reason.
- Prefer words that are already part of the existing vocabulary in the code corpus.

## Naming

### Temporary Variables

Temporary names consist of just **one word**, chosen by priority:
1. Usage — what it is used for.
2. Contents — what it holds.
3. Type — what kind of object it is.

```smalltalk
"Good — named by usage"
done := Set new.

"Acceptable — named by contents"
tasks := Set new.

"Avoid — named by type"
set := Set new.
```

Do not reuse a temporary name for a different value within the same method. Each
temporary should be assigned once.

### Method Arguments

Arguments are named after the **expected type**, prefixed by an article (`a`, `an`):

```smalltalk
add: anObject
name: aString
at: anInteger put: anObject
```

When the type prefix is not possible or desirable, use temporary-naming rules instead.

### Block Arguments

Block arguments are short, typically one word (often a single letter when the block
is small and the meaning is clear from context):

```smalltalk
self do: [:each | each process].
self collect: [:x | x squared].
self keysAndValuesDo: [:k :v | ...].
```

### Selectors

Method selectors should be **short and succinct**, one or two words if possible:

```smalltalk
"Good"
#elements

"Acceptable"
#elementsArray

"Avoid"
#arrayOfElements
```

### Instance Variables and Class Names

Keep them short and concise, following the same spirit as temporaries.

### No Abbreviations

Do not abbreviate words in names. Use the full word:

```smalltalk
"Avoid"
cmdNew
reqCount
msg

"Preferred"
commandNew
requestCount
message
```

## Methods

### Keep Methods Short

Avoid long methods. Ideally a method has one level of iteration and a clear
single purpose. Factor complex logic into helper methods and let the compiler
optimize.

```smalltalk
"Avoid"
baz
collection do: [:elem |
"first do this"
...bunch of code...
"then do that"
...more code...]

"Preferred"
baz
collection do: [:elem |
self doThis: elem; doThat: elem]
```

### No Nested Loops

Nested loops are highly discouraged. Factor the inner loop into its own method:

```smalltalk
"Avoid"
foo
[aCollection isEmpty] whileTrue: [
last := aCollection removeLast.
aCollection do: [:other | last use: other]]

"Preferred"
foo
[aCollection isEmpty] whileTrue: [
last := aCollection removeLast.
self useOthers: aCollection with: last]

useOthers: aCollection with: anObject
aCollection do: [:other | anObject use: other]
```

### No Keyword Message as Argument of Keyword Message

Use a temporary to break the nesting:

```smalltalk
"Avoid"
self foo: (self bar: aBaz)

"Preferred"
bar := self bar: aBaz.
self foo: bar
```

### No Comments

Comments are **not allowed**, except:
- As headers in methods that define public APIs.
- For _very_ special reasons (which almost never exist).

If you feel the need to write a comment in the middle of a method, refactor the
code into another method or create appropriate objects to make the code self-explanatory.

## Formatting

### File Structure (Tonel format)

Each `.st` file starts with an optional copyright header as a string literal,
followed by the class definition and then methods. Class definitions use the
standard Tonel syntax:

```smalltalk
"
Copyright (c) 2020 Aucerna.
See (MIT) license in root directory.
"

Class {
#name : #MyClass,
#superclass : #Object,
#instVars : [
'first',
'second'
],
#category : #Kernel
}
```

### Method Definitions

Each method is preceded by a category pragma and a blank line separates methods:

```smalltalk
{ #category : #accessing }
MyClass >> selector [
^value
]

{ #category : #accessing }
MyClass >> selector: anObject [
value := anObject
]
```

### Indentation

- Use **one tab** for indentation inside method bodies.
- Continuation lines in cascades and multi-keyword messages are indented with
one extra tab.

### Brackets and Blocks

- Opening brackets `[` stay on the same line as the expression that introduces them.
- Closing brackets `]` go on their own line only when the block spans multiple lines
and aligns with the opening expression. Short blocks stay on a single line.

```smalltalk
"Single-line block"
self do: [:each | each process].

"Multi-line block"
self do: [:element |
separate ifTrue: [separatorBlock value] ifFalse: [separate := true].
aBlock evaluateWith: element]
```

### Return Statements

Use `^` (caret) with a space before the returned expression. Early returns are the
preferred pattern for guard clauses:

```smalltalk
self isEmpty ifTrue: [^nil].
```

### Cascades

Cascades are preferred when sending multiple messages to the same receiver. For
more than two or three sends, break them across lines:

```smalltalk
"Short cascade on one line"
^self new add: anObject; yourself

"Long cascade across lines"
^self new
add: object1;
add: object2;
add: object3;
yourself
```

### Multi-keyword Selectors

When a method selector with many keywords is too long for one line, put each keyword
on its own line:

```smalltalk
Collection class >> with: object1
with: object2
with: object3
with: object4 [
^self new
add: object1;
add: object2;
add: object3;
add: object4;
yourself
]
```
73 changes: 2 additions & 71 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,11 @@ Please use github issue tracker to raise new issues.
Take care of the following before committing:

- Use short non-empty messages.
- Start the message with a <tag>: (i.e. bootstrap: fix whatever, or js: great feature added)
- Start the message with a [<tag>] (i.e. [bootstrap] fix whatever, or [js] great feature added)
- Always commit to a branch (pushing to main is not allowed anyway).
- Split commits in the branch to ease others reviewing and searching history.
- Do not put unrelated things in a same branch.
- Follow the code style rules stated in the next section.
- Follow the code style rules in [CODING_STYLE.md](CODING_STYLE.md).
- Keep the repo clean! Do not push blobs, autogenerated code, copy-pasted code that
could be autogenerated, garbage, etc.

# Code Style

This section explains the rules that need to be applied in order to get code accepted
for integration.

## General philosophy

As developers, we spend most of our time understanding existing code by reading it. For
that reason, in this project we aim to minimize the amount of text to be read. Shorter
code means less reading effort and more things fitting in the text editors, maximizing
screen space efficiency.

The following general rules apply:

- Short and concise names are expected for both variables, selectors and class names.
- We prefer words that are part of the existing vocabulary in the code corpus.
- All code is autoformatted, unless there is a _very_ special and specific reason.
- Simple optimizations should be left to be done dynamically by the runtime system,
instead of being written by the developer short and concise
- We favor simplicity and minimality to performance.
- Bee has been written using the rules explained here, giving it homogeneity
through all the code base. New code is expected to strictly follow them too.



## Methods

- Temporary variable names consist of just _one_ word. The name has to be related
primarily to the usage, secondarily to the contents and finally to the type.
As an example, `done := Set new` would be preferred to `tasks := Set new` which
would be preferred to `set := Set new` for a set that stores tasks that have been
done.
- Method arguments are named after the type expected, prefixed by an article. In
cases where it is not possible/desirable then temporary naming rules apply.
- Method selectors are preferred short and succinct, one or two words if possible.
As an example, `#elements` is preferred to `#elementsArray`, which is preferred
to `#arrayOfElements`

- _Comments are not allowed_, except as headers in methods that define public APIs,
or for _very_ special reasons (which almost never exist). If you are writing a
comment in the middle of a method, then refactor the thing into another method
or create according objects to make the code self understandable.
- Nested loops are highly discouraged. Again, factor them into methods and let
the compiler optimize. Example:

```
foo
[aCollection isEmpty] whileTrue: [
last := aCollection removeLast. aCollection do: [:other | last use: other]]

==>
foo
[aCollection isEmpty] whileTrue: [
last := aCollection removeLast. self useOthers: aCollection with: last]

useOthers: aCollection with: anObject
aCollection do: [:other | anObject use: other]
```

- Using keyword messages as argument of other keyword arguments is not allowed.
Example:

```
self foo: (self bar: aBaz)
==>
bar := self bar: aBaz.
self foo: bar
```

15 changes: 15 additions & 0 deletions bin/epm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
# epm - Egg Package Manager
# Finds and runs the egg binary with the EPM module

# Determine egg binary location
if [ -n "$EGG_HOME" ] && [ -x "$EGG_HOME/bin/egg" ]; then
EGG="$EGG_HOME/bin/egg"
elif command -v egg >/dev/null 2>&1; then
EGG=egg
else
echo "Error: egg binary not found. Set EGG_HOME or add egg to PATH." >&2
exit 1
fi

exec "$EGG" EPM "$@"
Loading
Loading