Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f0a44c7

Browse files
committedApr 29, 2021
pulling out less sensible/optimal string primitives
1 parent 4dd895b commit f0a44c7

13 files changed

+93
-138
lines changed
 

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Implemented thus far:
162162
* Strings:
163163
* simple string printing w/ `print`
164164
* fancier right-justified numeric output fields: `.rj`
165-
* `strcat`, `strcpy`, `strtok`, `memcpy`
165+
* `strtok`, `mempcpy`, `memset`, `mkbuf`, `free`
166166
* strong comparison with: `strlen`, `str=`, `str<`, `str>`
167167
* find a substring with `strfind`
168168
* '#' to end-of-line' for comments

‎contrib/dclang.nanorc

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ color brightred "(^|[[:space:]])((\!|\@|const|var|allot|create|\,|h\@|h\!|hkeys|
3030
color brightgreen "(^|[[:space:]])((times|again|exittimes|for|next|exitfor|i|j|k|if|else|endif|return)($|[[:space:]]))*"
3131
# other words
3232
color cyan "(^|[[:space:]])((cr|print|emit|uemit|ord|tohex|bytes32)($|[[:space:]]))*"
33-
color cyan "(^|[[:space:]])((free|strlen|str=|str<|str>|strfind|strcat|strcpy|strdup|strtok|memcpy|mempcpy|memset|clock|sleep)($|[[:space:]]))*"
33+
color cyan "(^|[[:space:]])((strlen|str=|str<|str>|strfind|strtok|mempcpy|memset|mkbuf|free|clock|sleep)($|[[:space:]]))*"
3434
color cyan "(^|[[:space:]])((fopen|fread|fseek|ftell|fwrite|fflush|fclose|redirect|resetout|flush|open|mkbuf|read|write|close)($|[[:space:]]))*"
3535
color cyan "(^|[[:space:]])((tcplisten|tcpaccept|tcpconnect|block_sigint|unblock_sigint)($|[[:space:]]))*"
3636
color yellow "(^|[[:space:]])((words|primitives|import|input)($|[[:space:]]))*"

‎examples/nano_syntax_highlighting_test.dc

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ drop dup over pick depth swap rot -rot nip tuck
1212
svpush svpop svpick svdrop svclear
1313
! @ const var allot create , h@ h! hkeys
1414
times again exittimes for next exitfor i j k if else endif return
15-
. h. .. .s .rj cr print emit uemit ord tohex bytes32 free
16-
strlen str= str< str> strfind strcat strcpy strdup strtok memcpy mempcpy memset
15+
. h. .. .s .rj cr print emit uemit ord tohex bytes32
16+
strlen str= str< str> strfind strtok mempcpy memset mkbuf free
1717
fopen fread fseek ftell fwrite fflush fclose redirect resetout flush
1818
open mkbuf read tcplisten tcpaccept tcpconnect clock sleep
1919
words primitives import input

‎examples/redis_example.dc

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ cr
3939
# END CODE
4040

4141
# STRING
42-
"Next, we'll do a simlar set/get, but with the grea J.S. Bach as the subject
42+
"Next, we'll do a simlar set/get, but with the great J.S. Bach as the subject
4343
of interest. The following is the output of two commands in succession:
4444

4545
\"Bach\" \"Best_composer\" redis_set print cr

‎examples/sorting.dc

+25-15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"string.dc" import
2+
13
var iters 24 iters !
24
var myarr iters @ allot
35

@@ -28,6 +30,7 @@ showarr
2830

2931
var :tempest_quote
3032
var :delimiters
33+
var token_hold
3134
var word_index 0 word_index !
3235
create tempest_words
3336

@@ -45,25 +48,32 @@ print cr
4548

4649
cr "The quote in question is: " print cr cr :tempest_quote @ print cr
4750

48-
: copy_token
49-
16 mkbuf swap strcpy ,
50-
;
51-
5251
: splitter_main
53-
0 :delimiters @ strtok dup
54-
0 <> if
55-
copy_token
56-
splitter_main
57-
endif
52+
0
53+
:delimiters @
54+
token_hold
55+
strtok
56+
dup
57+
0
58+
<>
59+
if
60+
,
61+
splitter_main
62+
endif
5863
;
5964

6065
: splitter
61-
:tempest_quote @ :delimiters @ strtok dup # ( token token )
62-
0 <> if
63-
copy_token
64-
splitter_main
65-
endif
66-
drop
66+
:tempest_quote @
67+
:delimiters @
68+
token_hold
69+
strtok
70+
dup # ( token token )
71+
0
72+
<>
73+
if
74+
,
75+
splitter_main
76+
endif
6777
;
6878

6979
: showstrs

‎examples/tcpclient.dc

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ var prompt "Please enter your message: " prompt !
2424

2525
: msg_to_buf
2626
zerobuf
27-
get_connbuf get_msg strcpy
27+
get_connbuf
28+
get_msg
29+
dup strlen
30+
mempcpy drop
2831
;
2932

3033
: client_connect "localhost" 5509 tcpconnect serv ! ;

‎examples/tcpserver.dc

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,21 @@ var accepted_conn
1414
: get_response_prefix response_prefix @ ;
1515
: get_response_prefix_len response_prefix_len @ ;
1616
: zerobuf get_connbuf 0 1024 memset ;
17-
: msgcpy get_received get_connbuf strcpy ;
17+
: copyinput
18+
get_received
19+
get_connbuf
20+
dup strlen
21+
mempcpy
22+
drop
23+
;
1824

1925
: read_incoming
2026
zerobuf
2127
get_accepted_conn get_connbuf 1023 read drop
2228
;
2329

2430
: concat_response
25-
msgcpy
31+
copyinput
2632
zerobuf
2733
get_connbuf get_response_prefix get_response_prefix_len mempcpy
2834
get_received dup strlen mempcpy

‎lib/redis.dc

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ var redis_socket -1 redis_socket !
7575
: _msg_to_buf
7676
_set_msg
7777
_zero_redis_buffer
78-
REDIS_BUFFER _get_msg strcpy drop
78+
REDIS_BUFFER _get_msg dup strlen mempcpy
79+
drop
7980
;
8081

8182
: _redis_connect

‎lib/string.dc

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
"deprecated_stack.dc" import
22

3+
: strdup
4+
# copies a string; leaves the new string's
5+
# beginning address on the stack
6+
dup strlen
7+
swap over mkbuf
8+
swap 2 pick mempcpy
9+
swap -
10+
;
11+
312
: _incr_saved_counter
413
svpop 1 + svpush
514
;

‎primitives.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,14 @@ void add_all_primitives()
135135
add_primitive("tonum", tonumfunc);
136136
add_primitive("tostr", tostrfunc);
137137
add_primitive("bytes32", bytes32func);
138-
add_primitive("mkbuf", mkbuffunc);
139-
add_primitive("free", freefunc);
140138
add_primitive("strlen", strlenfunc);
141139
add_primitive("str=", streqfunc);
142140
add_primitive("str<", strltfunc);
143141
add_primitive("str>", strgtfunc);
144142
add_primitive("strfind", strfindfunc);
145-
add_primitive("strcat", strcatfunc);
146-
add_primitive("strcpy", strcpyfunc);
147-
add_primitive("strdup", strdupfunc);
148143
add_primitive("strtok", strtokfunc);
149-
add_primitive("memcpy", memcpyfunc);
144+
add_primitive("mkbuf", mkbuffunc);
145+
add_primitive("free", freefunc);
150146
add_primitive("mempcpy", mempcpyfunc);
151147
add_primitive("memset", memsetfunc);
152148
// file
@@ -179,6 +175,9 @@ void add_all_primitives()
179175
// block a SIGINT
180176
add_primitive("block_sigint", blocksigintfunc);
181177
add_primitive("unblock_sigint", unblocksigintfunc);
178+
// os fork and exit
179+
add_primitive("fork", forkfunc);
180+
add_primitive("exit", exitfunc);
182181
// show defined words!
183182
add_primitive("words", showdefined);
184183
};

‎signal_ops.c

+23
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,26 @@ static void unblocksigintfunc()
1212
{
1313
sigprocmask(SIG_UNBLOCK, &block_sigint, NULL);
1414
}
15+
16+
17+
static void forkfunc()
18+
{
19+
// This function mainly exists so that a multi-client capable tcp/web server
20+
// can be had. It is assumed that the return value will be caught, inspected,
21+
// and handled by the caller, so this is really quite a simple c->dclang mapping.
22+
// TODO: a future enhancement might be to have a counting system in place for
23+
// avoiding fork-bomb DoS attacks. So, the introspection of a connection limit
24+
// before granting a new `fork`.
25+
push((DCLANG_INT32) fork());
26+
}
27+
28+
29+
static void exitfunc()
30+
{
31+
if (data_stack_ptr < 1) {
32+
printf("exit -- need an integer exit code on the stack");
33+
return;
34+
}
35+
DCLANG_INT32 code = (DCLANG_INT32) pop();
36+
exit(code);
37+
}

‎socket_ops.c

+12-12
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,22 @@ static void tcplistenfunc()
1414
printf("tcplisten -- need <port_number> on the\n");
1515
return;
1616
}
17-
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
18-
int true = 1;
19-
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int));
17+
DCLANG_INT32 sockfd = socket(AF_INET, SOCK_STREAM, 0);
18+
DCLANG_INT32 true = 1;
19+
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(DCLANG_INT32));
2020
if (sockfd < 0) {
2121
perror("tcplisten -- ERROR opening socket.");
2222
}
2323
bzero((char *) &serv_addr, sizeof(serv_addr));
24-
int portno = (int) pop();
24+
DCLANG_INT32 portno = (DCLANG_INT32) pop();
2525
serv_addr.sin_family = AF_INET;
2626
serv_addr.sin_addr.s_addr = INADDR_ANY;
2727
serv_addr.sin_port = htons(portno);
2828
if (bind(sockfd, (struct sockaddr *) &serv_addr,
2929
sizeof(serv_addr)) < 0)
3030
perror("ERROR on binding");
3131
listen(sockfd, 5);
32-
push((int) sockfd);
32+
push((DCLANG_INT32) sockfd);
3333
}
3434

3535

@@ -43,11 +43,11 @@ static void tcpacceptfunc()
4343
printf("tcpaccept -- need <socket> on the stack");
4444
return;
4545
}
46-
unsigned int clilen = sizeof(cli_addr);
47-
int sockfd = (int) pop();
48-
int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
46+
DCLANG_UINT32 clilen = sizeof(cli_addr);
47+
DCLANG_INT32 sockfd = (DCLANG_INT32) pop();
48+
DCLANG_INT32 newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
4949
if (newsockfd < 0) perror("tcpaccept -- ERROR on accept step!");
50-
push((int) newsockfd);
50+
push((DCLANG_INT32) newsockfd);
5151
}
5252

5353

@@ -59,9 +59,9 @@ static void tcpconnectfunc()
5959
printf("tcpconnect -- need <host> <port> on the stack");
6060
return;
6161
}
62-
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
62+
DCLANG_INT32 sockfd = socket(AF_INET, SOCK_STREAM, 0);
6363
if (sockfd < 0) perror("tcpconnect -- ERROR opening socket");
64-
int portno = (int) pop();
64+
DCLANG_INT32 portno = (DCLANG_INT32) pop();
6565
struct sockaddr_in host_addr;
6666
char *servername = (char *) (DCLANG_UINT) pop();
6767
struct hostent *server = gethostbyname(servername);
@@ -75,5 +75,5 @@ static void tcpconnectfunc()
7575
host_addr.sin_port = htons(portno);
7676
if (connect(sockfd, (struct sockaddr *)&host_addr, sizeof(host_addr)) < 0)
7777
perror("tcpconnect -- ERROR connecting");
78-
push((int) sockfd);
78+
push((DCLANG_INT32) sockfd);
7979
}

‎string_ops.c

-96
Original file line numberDiff line numberDiff line change
@@ -418,80 +418,6 @@ static void strfindfunc()
418418
push((DCLANG_INT) strstr(str1, str2));
419419
}
420420

421-
// destructive/creative string functions:
422-
static void strcatfunc()
423-
{
424-
if (data_stack_ptr < 2)
425-
{
426-
printf("strcat -- needs <dest> <source> string pointers on stack! ");
427-
return;
428-
}
429-
DCLANG_UINT string_uint_addr2 = (DCLANG_UINT) pop();
430-
DCLANG_UINT string_uint_addr1 = (DCLANG_UINT) pop();
431-
if (string_uint_addr1 < MIN_STR || string_uint_addr1 > MAX_STR)
432-
{
433-
perror("strcat -- <dest> (first) string address out-of-range.");
434-
return;
435-
}
436-
if (string_uint_addr2 < MIN_STR || string_uint_addr2 > MAX_STR)
437-
{
438-
perror("strcat -- <source> (second) string address out-of-range.");
439-
return;
440-
}
441-
char *str1 = (char *) string_uint_addr1;
442-
char *str2 = (char *) string_uint_addr2;
443-
push((DCLANG_INT) strcat(str1, str2));
444-
}
445-
446-
static void strcpyfunc()
447-
{
448-
if (data_stack_ptr < 2)
449-
{
450-
printf("strcpy -- needs <dest> <source> string pointers on stack! ");
451-
return;
452-
}
453-
DCLANG_UINT string_uint_addr2 = (DCLANG_UINT) pop();
454-
DCLANG_UINT string_uint_addr1 = (DCLANG_UINT) pop();
455-
if (string_uint_addr1 < MIN_STR || string_uint_addr1 > MAX_STR)
456-
{
457-
perror("strcpy -- <dest> (first) string address out-of-range.");
458-
return;
459-
}
460-
if (string_uint_addr2 < MIN_STR || string_uint_addr2 > MAX_STR)
461-
{
462-
perror("strcpy -- <source> (second) string address out-of-range.");
463-
return;
464-
}
465-
char *str1 = (char *) string_uint_addr1;
466-
char *str2 = (char *) string_uint_addr2;
467-
push((DCLANG_INT) strcpy(str1, str2));
468-
}
469-
470-
static void strdupfunc()
471-
{
472-
if (data_stack_ptr < 1)
473-
{
474-
printf("strdup -- needs <string> string pointer on stack! ");
475-
return;
476-
}
477-
DCLANG_UINT string_uint_addr = (DCLANG_UINT) pop();
478-
if (string_uint_addr < MIN_STR || string_uint_addr > MAX_STR)
479-
{
480-
perror("strdup -- string address out-of-range.");
481-
return;
482-
}
483-
char *str1 = strdup((char *) string_uint_addr);
484-
DCLANG_UINT str1addr = (DCLANG_UINT) str1;
485-
if (str1addr < MIN_STR || MIN_STR == 0)
486-
{
487-
MIN_STR = str1addr;
488-
}
489-
if (str1addr > MAX_STR || MAX_STR == 0)
490-
{
491-
MAX_STR = str1addr;
492-
}
493-
push((DCLANG_UINT) str1);
494-
}
495421

496422
static void strtokfunc()
497423
{
@@ -524,28 +450,6 @@ static void strtokfunc()
524450
push((DCLANG_INT) strtok_r(str1, str2, savepoint_ptr));
525451
}
526452

527-
static void memcpyfunc()
528-
{
529-
if (data_stack_ptr < 3)
530-
{
531-
printf("memcpy -- needs <dest> <source> <size> on stack! ");
532-
return;
533-
}
534-
DCLANG_UINT size = (DCLANG_UINT) pop();
535-
DCLANG_UINT source = (DCLANG_UINT) pop();
536-
DCLANG_UINT dest = (DCLANG_UINT) pop();
537-
if ((dest != 0) && (dest < MIN_STR || dest > MAX_STR))
538-
{
539-
perror("memcpy -- <dest> string address out-of-range.");
540-
return;
541-
}
542-
if (source < MIN_STR || source > MAX_STR)
543-
{
544-
perror("memcpy -- <source> string address out-of-range.");
545-
return;
546-
}
547-
push((DCLANG_UINT) memcpy((char *)dest, (char *)source, (DCLANG_UINT) size));
548-
}
549453

550454
static void mempcpyfunc()
551455
{

0 commit comments

Comments
 (0)