Day 1. Assembly code is being generated, on a monkey see, monkey do basis;
but it doesn't link because of a missing library; and having moved source files around the Makefile currently doesn't work.
This commit is contained in:
parent
8e9ad73229
commit
882f991db4
13 changed files with 206 additions and 36 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -57,3 +57,6 @@ dkms.conf
|
|||
.project
|
||||
.settings/
|
||||
build/
|
||||
|
||||
# Munit
|
||||
src/munit.*
|
||||
|
|
|
|||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "munit"]
|
||||
path = munit
|
||||
url = https://github.com/nemequ/munit.git
|
||||
2
Makefile
2
Makefile
|
|
@ -15,7 +15,7 @@ else
|
|||
$(error Build mode $(BUILD_MODE) not supported by this Makefile)
|
||||
endif
|
||||
|
||||
SRC_DIR=$(PROJECT_ROOT)/src
|
||||
SRC_DIR=$(PROJECT_ROOT)/src/c
|
||||
|
||||
all: grendel
|
||||
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -36,11 +36,11 @@ Tags will be allocated as follows:
|
|||
|
||||
| 3-bit value | 7-bit value | (Hex) | Interpretation |
|
||||
| ----------- | ----------- | ----- | ------------------------------------------------------------ |
|
||||
| 0 | 0 | 0x0 | a pointer; an offset into the vector of words. |
|
||||
| 1 | 1 | 0x1 | a signed 28 bit integer. |
|
||||
| 2 | 2 | 0x2 | a character; possibly just a byte, or possibly a 16 bit wchar. |
|
||||
| 3 | 3 | 0x3 | unassigned (possibly a floating point number, later.) |
|
||||
| 4 | 4 | 0x4 | unassigned |
|
||||
| 0 | 0 | 0x0 | an error object, whose payload is a 3 character error code. |
|
||||
| 1 | 1 | 0x1 | a pointer; an offset into the vector of words. |
|
||||
| 2 | 2 | 0x2 | a signed 28 bit integer. |
|
||||
| 3 | 3 | 0x3 | a character; possibly just a byte, or possibly a 16 bit wchar. |
|
||||
| 4 | 4 | 0x4 | unassigned (possibly a floating point number, later.) |
|
||||
| 5 | 5 | 0x5 | unassigned |
|
||||
| 6 | 6 | 0x6 | unassigned |
|
||||
| 7 | 7 | 0x7 | a cons cell |
|
||||
|
|
|
|||
1
munit
Submodule
1
munit
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit fbbdf1467eb0d04a6ee465def2e529e4c87f2118
|
||||
26
src/c/day1.c
Normal file
26
src/c/day1.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* day1.c
|
||||
*
|
||||
* Grendel: a compiling Beowulf reimplementation.
|
||||
*
|
||||
* Day 1 of work towards a compiler... eventually..
|
||||
*
|
||||
* This is a straight copy of Noah Zentzis' work. There's no original work of
|
||||
* mine here, yet
|
||||
*
|
||||
* (c) 2026 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
__attribute__((__cdecl__))
|
||||
extern int lisp_entry();
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
int val = lisp_entry();
|
||||
printf("%d\n", val);
|
||||
return 0;
|
||||
}
|
||||
29
src/c/error.c
Normal file
29
src/c/error.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* error.c
|
||||
*
|
||||
* Grendel: a compiling Beowulf reimplementation.
|
||||
*
|
||||
* The error handling subsystem.
|
||||
*
|
||||
* Error codes are detailed in section 6.3, page 32, of the
|
||||
* Lisp 1.5 Programmer's Manual. I shall in so far as possible follow
|
||||
* those codes.
|
||||
*
|
||||
* (c) 2026 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "memory.h"
|
||||
|
||||
uint32_t make_error( char* code) {
|
||||
uint32_t error = 0;
|
||||
|
||||
strncpy( (char *)((&error) &1), code, 3);
|
||||
|
||||
return error;
|
||||
}
|
||||
45
src/c/error.h
Normal file
45
src/c/error.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* error.h
|
||||
*
|
||||
* Grendel: a compiling Beowulf reimplementation.
|
||||
*
|
||||
* The error handling subsystem.
|
||||
*
|
||||
* Error codes are detailed in section 6.3, page 32, of the
|
||||
* Lisp 1.5 Programmer's Manual. I shall in so far as possible follow
|
||||
* those codes.
|
||||
*
|
||||
* (c) 2026 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#ifndef __grendel_error_h
|
||||
#define __grendel_error_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t make_error( char* code);
|
||||
|
||||
/**
|
||||
* @brief error codes
|
||||
*
|
||||
* Error codes are detailed in section 6.3, page 32, of the
|
||||
* Lisp 1.5 Programmer's Manual. I shall in so far as possible follow
|
||||
* those codes.
|
||||
*
|
||||
* Error codes comprise a one or two alphabetic character category, followed
|
||||
* by a single digit number. A space is shown in the manual between the
|
||||
* category and the number, but I have not followed that here for reasons.
|
||||
*/
|
||||
|
||||
#define APPLIED_FUNCTION_CALLED_ERROR (make_error( "A1"))
|
||||
#define UNDEFINED_FUNCTION_APPLY_ERROR (make_error( "A2"))
|
||||
#define COND_UNSATISFIED_ERROR (make_error( "A3"))
|
||||
#define SETQ_ON_NONEXISTANT_VAR_ERROR (make_error( "A4"))
|
||||
#define SET_ON_NONEXISTANT_VAR_ERROR (make_error( "A5"))
|
||||
#define NO_TARGET_FOR_GO_ERROR (make_error( "A6"))
|
||||
#define TOO_MANY_ARGUMENTS_ERROR (make_error( "A7"))
|
||||
#define UNBOUND_VARIABLE_ERROR (make_error( "A8"))
|
||||
#define UNDEFINED_FUNCTION_EVAL_ERROR (make_error( "A9"))
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,11 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "version.h"
|
||||
|
||||
__attribute__((__cdecl__))
|
||||
extern int lisp_entry();
|
||||
|
||||
|
||||
void showbits( unsigned int x )
|
||||
{
|
||||
|
|
@ -28,18 +33,12 @@ void showbits( unsigned int x )
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
printf( "Grendel:\n");
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < 8; i++) {
|
||||
printf( "\ti = %d (%b, 0x%x);\n", i, i, i);
|
||||
}
|
||||
for ( ; i < 128; i++) {
|
||||
if ((i & TAG32MASK) == TAG32MASK) {
|
||||
printf( "\ti = %d (%b, 0x%x);\n", i, i, i);
|
||||
}
|
||||
}
|
||||
printf( "Grendel, a compiler for Beowulf: version %s\n", VERSION);
|
||||
|
||||
int val = lisp_entry();
|
||||
printf("%d\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
src/c/lisp.c
Normal file
19
src/c/lisp.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* lisp.c
|
||||
*
|
||||
* Grendel: a compiling Beowulf reimplementation.
|
||||
*
|
||||
* The compiler... eventually..
|
||||
*
|
||||
* Error codes are detailed in section 6.3, page 32, of the
|
||||
* Lisp 1.5 Programmer's Manual. I shall in so far as possible follow
|
||||
* those codes.
|
||||
*
|
||||
* (c) 2026 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -16,64 +16,64 @@
|
|||
|
||||
/* Tags for 32 bit objects, with 3 bits of tag an one mark bit */
|
||||
|
||||
#define ERRORTV (0)
|
||||
/**
|
||||
* @brief This pointer object is an actual pointer -- an offset into consspace.
|
||||
*/
|
||||
#define OFFSETTV (0)
|
||||
#define OFFSETTV (1)
|
||||
/**
|
||||
* @brief This pointer object is actually a 28 bit integer value.
|
||||
*/
|
||||
#define INTEGERTV (1)
|
||||
#define INTEGERTV (2)
|
||||
/**
|
||||
* @brief A character; initially just a byte. but potentially a 16 bit wchar.
|
||||
*/
|
||||
#define CHARTV (2)
|
||||
#define CHARTV (3)
|
||||
/**
|
||||
* @brief A 16 bit floating point number. (future expansion)
|
||||
*
|
||||
* Yes, it could be 28 bit, but I think that would hurt my brain.
|
||||
*/
|
||||
#define FLOATTV (3)
|
||||
#define FLOATTV (4)
|
||||
|
||||
/*
|
||||
* Values 4..6 inclusive reserved further data types, including maybe
|
||||
* implementing reals later.
|
||||
* Values 5 and 6 are available for further 32 bit data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @bried This is not actually a pointer at all but the first word of a cell.
|
||||
*/
|
||||
#define CELLTV (7)
|
||||
#define CELLTV (7)
|
||||
|
||||
/**
|
||||
* @brief this cell is a symbol
|
||||
*/
|
||||
#define SYMBOLTV (0xf)
|
||||
#define SYMBOLTV (0xf)
|
||||
|
||||
/**
|
||||
* @brief this cell is a pointer to a compiled function
|
||||
*/
|
||||
#define FUNCTIONTV (0x17)
|
||||
#define FUNCTIONTV (0x17)
|
||||
|
||||
/**
|
||||
* @brief This cell is pointer to a compiled special form
|
||||
*/
|
||||
#define SPECIALTV (0x1f)
|
||||
#define SPECIALTV (0x1f)
|
||||
|
||||
/**
|
||||
* @brief this cell is a rational number (future expansion)
|
||||
*/
|
||||
#define RATIOTV (0x27)
|
||||
#define RATIOTV (0x27)
|
||||
|
||||
/**
|
||||
* @brief this cell is a digit of a big number (future expansion)
|
||||
*/
|
||||
#define BIGNUMTV (0x2f)
|
||||
#define BIGNUMTV (0x2f)
|
||||
|
||||
/**
|
||||
* @brief this cell is part of a string (future expansion)
|
||||
*/
|
||||
#define STRINGTV (0x37)
|
||||
#define STRINGTV (0x37)
|
||||
|
||||
// The possible potential values remain unassigned:
|
||||
// i = 63 (111111, 0x3f);
|
||||
|
|
@ -85,14 +85,14 @@
|
|||
// i = 111 (1101111, 0x6f);
|
||||
// i = 119 (1110111, 0x77);
|
||||
|
||||
#define FREETV (0x7f)
|
||||
#define FREETV (0x7f)
|
||||
|
||||
#define MARKMASK ((unsigned int)1)
|
||||
#define TAG32MASK ((unsigned int)7)
|
||||
#define TAG64MASK ((unsigned int)0xf)
|
||||
#define MARKMASK ((uint64_t)1)
|
||||
#define TAG32MASK ((uint64_t)7)
|
||||
#define TAG64MASK ((uint64_t)0xf)
|
||||
|
||||
#define MASK64 (0xffffffffffffffff)
|
||||
#define MASK32 (0xffffffff)
|
||||
#define MASK64 ((uint64_t)0xffffffffffffffff)
|
||||
#define MASK32 ((uint64_t)0xffffffff)
|
||||
|
||||
/**
|
||||
* @brief Return the mark bit of this object.
|
||||
15
src/c/version.h
Normal file
15
src/c/version.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* version.h
|
||||
*
|
||||
* Grendel: a compiling Beowulf reimplementation.
|
||||
*
|
||||
* (c) 2026 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#ifndef __grendel_version_h
|
||||
#define __grendel_version_h
|
||||
|
||||
#define VERSIOM "Aelfhere"
|
||||
|
||||
#ifndef
|
||||
30
src/guile/day1.scm
Normal file
30
src/guile/day1.scm
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
(define emit (lambda args (apply simple-format #t args)
|
||||
(newline)))
|
||||
|
||||
(define (compile-program program)
|
||||
(emit ".text")
|
||||
(emit ".p2align 4,,15")
|
||||
(emit ".globl lisp_entry")
|
||||
(emit "lisp_entry:")
|
||||
|
||||
; handle incoming call from C
|
||||
(emit "push %esi")
|
||||
(emit "push %edi")
|
||||
(emit "push %edx")
|
||||
|
||||
; our code goes here
|
||||
(emit "movl $42, %eax")
|
||||
|
||||
; restore state for return to C
|
||||
(emit "pop %edx")
|
||||
(emit "pop %edi")
|
||||
(emit "pop %esi")
|
||||
(emit "ret"))
|
||||
|
||||
(define (compile-to-binary program)
|
||||
(begin
|
||||
(with-output-to-file "/tmp/compiled.s"
|
||||
(lambda () (compile-program program)))
|
||||
(system "gcc -fomit-frame-pointer -m32 /tmp/compiled.s src/c/day1.c")))
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue