Skip to content

Commit 486075a

Browse files
committed
Added list (and other) native functions, library code cleanup and stability improvements
1 parent 6ae4909 commit 486075a

20 files changed

+429
-547
lines changed

README.md

+19-2
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,31 @@ The process of adding additional native functions to the Lox interpreter has fou
105105

106106
Doing these steps correctly and in order ensures that the project should remain compilable at all times. Look out for both compilation and linker errors.
107107

108+
## Additions to the Lox Language
109+
110+
A number of native functions not specified in the book "Crafting Interpreters" have been added to the base language, as well as hetrogeneous list syntax using `[` and `]`:
111+
112+
```javascript
113+
var list = [ 1, "abc", 2.2 ];
114+
print length(list); // "3"
115+
list[2] = 3.3; // list is now [ 1, "abc", 3.3 ];
116+
delete(list, 1); // list is now [ 1, 3.3 ];
117+
print length(list); // "2"
118+
append(list, "xyz"); // list is now [ 1, 3.3, "xyz" ];
119+
print list[2]; // "xyz"
120+
var s1 = tostring(2.2); // s1 is "2.2"
121+
var s2 = "abcde";
122+
var s3 = substring(s2, 2, 3); // s3 is "cd"
123+
```
124+
108125
## Future Developments
109126

110127
There are a number of ideas for the future direction of this library:
111128

112-
* Stability: likely to be many bugs in non-core library code, and faulty Lox input can crash the board (fixed)
129+
* Stability: likely to be many bugs in non-core library. Faulty Lox input can crash the board (fixed). Errors generated in native functions cause the interpreter to crash (fixed). Loading from USB is not stable.
113130
* Complete support for more "Arduino.h" functions
114131
* Support for Arduino_GigaDisplayTouch
115-
* Support for running scripts via a web interface (console-in-a-web-page) (#define CLOX_WEB_CONSOLE 1)
132+
* Support for running scripts via a web interface (console-in-a-web-page) (use #define CLOX_WEB_CONSOLE 1 in "clox_gfx_config.h")
116133
* Use of the M4 co-processor as a graphics accelerator
117134
* Changing the Lox interpreter language (not the JIT backend) to something less like JavaScript (GFX-Basic?)
118135
* Adding to the ArduinoGraphics library (filled triangles, more fonts etc.)
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
#define SECRET_SSID "MyNetwork"
2-
#define SECRET_PASS "<passphrase>"
1+
#define SECRET_SSID "MyNetwork"
2+
#define SECRET_PASS "<passphrase>"
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#define CLOX_GRAPHICS 0
2-
#define CLOX_USB_HOST 0
3-
#define CLOX_WEB_CONSOLE 0
4-
#define CLOX_USE_SDRAM 0
1+
#define CLOX_GRAPHICS 0
2+
#define CLOX_USB_HOST 0
3+
#define CLOX_WEB_CONSOLE 0
4+
#define CLOX_USE_SDRAM 0

examples/clox_gfx_demo/web_console.h

+82-82
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,83 @@
1-
const char web_console[] = R"(<!DOCTYPE html>
2-
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>Web Terminal</title>
7-
<style>
8-
#terminal {
9-
background-color: black;
10-
color: lightblue;
11-
padding: 2px;
12-
font-family: monospace;
13-
font-size: 14px;
14-
width: 80%;
15-
height: 400px;
16-
overflow: auto;
17-
white-space: pre-wrap;
18-
overflow-y: scroll;
19-
word-wrap: break-word;
20-
}
21-
#input {
22-
position: absolute;
23-
left: -9999px;
24-
}
25-
</style>
26-
</head>
27-
<body>
28-
<div id="terminal"></div>
29-
<input id="input" type="text">
30-
<script>
31-
const terminal = document.getElementById('terminal');
32-
const input = document.getElementById('input');
33-
const ws = new WebSocket('ws://%LOCAL_ADDRESS_AND_PORT%');
34-
var current_line = '';
35-
36-
ws.onopen = () => {
37-
terminal.textContent += 'Connected to server\n';
38-
};
39-
40-
ws.onmessage = (event) => {
41-
terminal.textContent += event.data;
42-
terminal.scrollTop = terminal.scrollHeight;
43-
};
44-
45-
terminal.addEventListener('click', () => {
46-
input.focus();
47-
});
48-
49-
input.addEventListener('input', () => {
50-
terminal.textContent += input.value;
51-
current_line += input.value;
52-
input.value = '';
53-
terminal.scrollTop = terminal.scrollHeight;
54-
});
55-
56-
input.addEventListener('paste', (event) => {
57-
let paste = (event.clipboardData || window.clipboardData).getData('text');
58-
event.preventDefault();
59-
const lines = paste.split(/(\r\n|\n|\r)/);
60-
for (let line of lines) {
61-
ws.send(line + '\n');
62-
}
63-
});
64-
65-
input.addEventListener('keydown', (event) => {
66-
if (event.key === 'Enter') {
67-
event.preventDefault();
68-
terminal.textContent += '\n';
69-
ws.send(current_line + '\n');
70-
terminal.scrollTop = terminal.scrollHeight;
71-
current_line = '';
72-
}
73-
else if (event.key === 'Delete' || event.key === 'Backspace') {
74-
if (current_line.length > 0) {
75-
current_line = current_line.slice(0, -1);
76-
terminal.textContent = terminal.textContent.slice(0, -1);
77-
}
78-
}
79-
});
80-
</script>
81-
</body>
82-
</html>
1+
const char web_console[] = R"(<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Web Terminal</title>
7+
<style>
8+
#terminal {
9+
background-color: black;
10+
color: lightblue;
11+
padding: 2px;
12+
font-family: monospace;
13+
font-size: 14px;
14+
width: 80%;
15+
height: 400px;
16+
overflow: auto;
17+
white-space: pre-wrap;
18+
overflow-y: scroll;
19+
word-wrap: break-word;
20+
}
21+
#input {
22+
position: absolute;
23+
left: -9999px;
24+
}
25+
</style>
26+
</head>
27+
<body>
28+
<div id="terminal"></div>
29+
<input id="input" type="text">
30+
<script>
31+
const terminal = document.getElementById('terminal');
32+
const input = document.getElementById('input');
33+
const ws = new WebSocket('ws://%LOCAL_ADDRESS_AND_PORT%');
34+
var current_line = '';
35+
36+
ws.onopen = () => {
37+
terminal.textContent += 'Connected to server\n';
38+
};
39+
40+
ws.onmessage = (event) => {
41+
terminal.textContent += event.data;
42+
terminal.scrollTop = terminal.scrollHeight;
43+
};
44+
45+
terminal.addEventListener('click', () => {
46+
input.focus();
47+
});
48+
49+
input.addEventListener('input', () => {
50+
terminal.textContent += input.value;
51+
current_line += input.value;
52+
input.value = '';
53+
terminal.scrollTop = terminal.scrollHeight;
54+
});
55+
56+
input.addEventListener('paste', (event) => {
57+
let paste = (event.clipboardData || window.clipboardData).getData('text');
58+
event.preventDefault();
59+
const lines = paste.split(/(\r\n|\n|\r)/);
60+
for (let line of lines) {
61+
ws.send(line + '\n');
62+
}
63+
});
64+
65+
input.addEventListener('keydown', (event) => {
66+
if (event.key === 'Enter') {
67+
event.preventDefault();
68+
terminal.textContent += '\n';
69+
ws.send(current_line + '\n');
70+
terminal.scrollTop = terminal.scrollHeight;
71+
current_line = '';
72+
}
73+
else if (event.key === 'Delete' || event.key === 'Backspace') {
74+
if (current_line.length > 0) {
75+
current_line = current_line.slice(0, -1);
76+
terminal.textContent = terminal.textContent.slice(0, -1);
77+
}
78+
}
79+
});
80+
</script>
81+
</body>
82+
</html>
8383
)";

library.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=clox_gfx
2-
version=0.0.4
2+
version=0.0.5
33
author=Richard Spencer <cpptutor@outlook.com>
44
maintainer=Richard Spencer <cpptutor@outlook.com>
55
sentence=Port of the Lox interpreted programming language to Arduino
6-
paragraph=(Experimental) Very early alpha code, please check the repository for a more recent version. Intended for Giga R1 WiFi and Display with USB storage, most of the functionality can be disabled for other boards.
6+
paragraph=(Experimental) Library code is stable, but please check the repository for a more recent version. Intended for GIGA R1 WiFi and Display with USB storage, most of the functionality can be disabled for other boards.
77
category=Other
88
url=https://github.com/cpp-tutor/clox-gfx
99
depends=ArduinoGraphics, Arduino_USBHostMbed5, WebSockets2_Generic

src/chunk.c

-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ void freeChunk(Chunk* chunk) {
1717
freeValueArray(&chunk->constants);
1818
initChunk(chunk);
1919
}
20-
/* Chunks of Bytecode write-chunk < Chunks of Bytecode write-chunk-with-line
21-
void writeChunk(Chunk* chunk, uint8_t byte) {
22-
*/
2320
void writeChunk(Chunk* chunk, uint8_t byte, int line) {
2421
if (chunk->capacity < chunk->count + 1) {
2522
int oldCapacity = chunk->capacity;

src/chunk.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ typedef enum {
1515
OP_GET_GLOBAL,
1616
OP_DEFINE_GLOBAL,
1717
OP_SET_GLOBAL,
18+
OP_BUILD_LIST,
19+
OP_INDEX_SUBSCR,
20+
OP_STORE_SUBSCR,
1821
OP_GET_UPVALUE,
1922
OP_SET_UPVALUE,
2023
OP_GET_PROPERTY,
@@ -54,9 +57,6 @@ typedef struct {
5457

5558
void initChunk(Chunk* chunk);
5659
void freeChunk(Chunk* chunk);
57-
/* Chunks of Bytecode write-chunk-h < Chunks of Bytecode write-chunk-with-line-h
58-
void writeChunk(Chunk* chunk, uint8_t byte);
59-
*/
6060
void writeChunk(Chunk* chunk, uint8_t byte, int line);
6161
int addConstant(Chunk* chunk, Value value);
6262

src/clox_gfx.h

+14-14
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ Value gfx_printFloat(double num, int digits);
6464
if (arity != argCount) { \
6565
runtimeError("Expected %d arguments but got %d in call to %s().", \
6666
arity, argCount, #type); \
67-
return NIL_VAL; \
67+
return ERR_VAL; \
6868
} \
6969
for (int arg = 0; arg != argCount; ++arg) { \
7070
if (!IS_NUMBER(args[arg])) { \
7171
runtimeError("Expected a number for argument %d call to %s().", \
7272
arg + 1, #type); \
73-
return NIL_VAL; \
73+
return ERR_VAL; \
7474
} \
7575
} \
7676
return gfx_##type(GFX_ARGS_##arity); \
@@ -83,17 +83,17 @@ Value gfx_printFloat(double num, int digits);
8383
if (2 != argCount) { \
8484
runtimeError("Expected %d arguments but got %d in call to %s().", \
8585
2, argCount, #type); \
86-
return NIL_VAL; \
86+
return ERR_VAL; \
8787
} \
8888
if (!IS_NUMBER(args[0])) { \
8989
runtimeError("Expected a number for argument %d call to %s().", \
9090
1, #type); \
91-
return NIL_VAL; \
91+
return ERR_VAL; \
9292
} \
9393
if (!IS_STRING(args[1])) { \
9494
runtimeError("Expected a string for argument %d call to %s().", \
9595
2, #type); \
96-
return NIL_VAL; \
96+
return ERR_VAL; \
9797
} \
9898
return gfx_##type(GFX_ARGS_NUM_STR); \
9999
}
@@ -105,17 +105,17 @@ Value gfx_printFloat(double num, int digits);
105105
if (2 != argCount) { \
106106
runtimeError("Expected %d arguments but got %d in call to %s().", \
107107
2, argCount, #type); \
108-
return NIL_VAL; \
108+
return ERR_VAL; \
109109
} \
110110
if (!IS_NUMBER(args[0])) { \
111111
runtimeError("Expected a number for argument %d call to %s().", \
112112
1, #type); \
113-
return NIL_VAL; \
113+
return ERR_VAL; \
114114
} \
115115
if (!IS_BOOL(args[1])) { \
116116
runtimeError("Expected a Boolean for argument %d call to %s().", \
117117
2, #type); \
118-
return NIL_VAL; \
118+
return ERR_VAL; \
119119
} \
120120
return gfx_##type(GFX_ARGS_NUM_BOOL); \
121121
}
@@ -127,22 +127,22 @@ Value gfx_printFloat(double num, int digits);
127127
if (3 != argCount) { \
128128
runtimeError("Expected %d arguments but got %d in call to %s().", \
129129
3, argCount, #type); \
130-
return NIL_VAL; \
130+
return ERR_VAL; \
131131
} \
132132
if (!IS_STRING(args[0])) { \
133133
runtimeError("Expected a string for argument %d call to %s().", \
134134
1, #type); \
135-
return NIL_VAL; \
135+
return ERR_VAL; \
136136
} \
137137
if (!IS_NUMBER(args[1])) { \
138138
runtimeError("Expected a number for argument %d call to %s().", \
139139
2, #type); \
140-
return NIL_VAL; \
140+
return ERR_VAL; \
141141
} \
142142
if (!IS_NUMBER(args[2])) { \
143143
runtimeError("Expected a number for argument %d call to %s().", \
144144
3, #type); \
145-
return NIL_VAL; \
145+
return ERR_VAL; \
146146
} \
147147
return gfx_##type(GFX_ARGS_STR_NUM_NUM); \
148148
}
@@ -154,12 +154,12 @@ Value gfx_printFloat(double num, int digits);
154154
if (1 != argCount) { \
155155
runtimeError("Expected %d arguments but got %d in call to %s().", \
156156
1, argCount, #type); \
157-
return NIL_VAL; \
157+
return ERR_VAL; \
158158
} \
159159
if (!IS_STRING(args[0])) { \
160160
runtimeError("Expected a string for argument %d call to %s().", \
161161
1, #type); \
162-
return NIL_VAL; \
162+
return ERR_VAL; \
163163
} \
164164
return gfx_##type(GFX_ARGS_STR); \
165165
}

0 commit comments

Comments
 (0)