-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathwelcome.sh
executable file
·91 lines (83 loc) · 2.46 KB
/
welcome.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/bin/sh
set -e -u -f
LC_ALL=C
: $((i = name = 0))
_main() {
let name; let i
_malloc name 100
i=0
printf "What is your name?\n"
while { _getchar _$((name + i)); [ $((_$((name + i)))) != -1 ]; } && [ $((_$((name + i)))) != $__NEWLINE__ ]; do
: $((i += 1))
done
: $((_$((name + i)) = __NUL__))
printf "Hello, "
_put_pstr __ $name
printf "\n"
endlet $1 i name
}
# Character constants
readonly __NUL__=0
readonly __NEWLINE__=10
# Runtime library
__stdin_buf=
__stdin_line_ending=0 # Line ending, either -1 (EOF) or 10 ('\n')
_getchar() {
if [ -z "$__stdin_buf" ]; then # need to get next line when buffer empty
if [ $__stdin_line_ending != 0 ]; then # Line is empty, return line ending
: $(($1 = __stdin_line_ending))
__stdin_line_ending=0 # Reset line ending for next getchar call
return
fi
IFS= # don't split input
if read -r __stdin_buf ; then # read next line into $__stdin_buf
if [ -z "$__stdin_buf" ] ; then # an empty line implies a newline character
: $(($1 = 10)) # next getchar call will read next line
return
fi
__stdin_line_ending=10
else
if [ -z "$__stdin_buf" ] ; then # EOF reached when read fails
: $(($1 = -1))
return
else
__stdin_line_ending=-1
fi
fi
fi
__c=$(printf "%d" "'${__stdin_buf%"${__stdin_buf#?}"}"); __c=$((__c > 0 ? __c : 256 + __c))
: $(($1 = __c))
__stdin_buf="${__stdin_buf#?}" # remove the current char from $__stdin_buf
}
__ALLOC=1 # Starting heap at 1 because 0 is the null pointer.
_malloc() { # $2 = object size
: $((_$__ALLOC = $2)) # Track object size
: $(($1 = $__ALLOC + 1))
: $((__ALLOC += $2 + 1))
}
_put_pstr() {
: $(($1 = 0)); shift # Return 0
__addr=$1; shift
while [ $((__c = _$__addr)) != 0 ]; do
printf \\$((__c/64))$((__c/8%8))$((__c%8))
: $((__addr += 1))
done
}
# Local variables
__=0
__SP=0
let() { # $1: variable name, $2: value (optional)
: $((__SP += 1)) $((__$__SP=$1)) # Push
: $(($1=${2-0})) # Init
}
endlet() { # $1: return variable
# $2...: function local variables
__ret=$1 # Don't overwrite return value
: $((__tmp = $__ret))
while [ $# -ge 2 ]; do
: $(($2 = __$__SP)) $((__SP -= 1)); # Pop
shift;
done
: $(($__ret=__tmp)) # Restore return value
}
_main __