-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathstdio.h
139 lines (112 loc) · 2.99 KB
/
stdio.h
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef __STDIO_H__
#define __STDIO_H__
#include <assert.h>
#define EOF (-1)
int puts(char* str)
{
asm (str) -> void { syscall print_str; };
asm () -> void { syscall print_endl; };
return 0;
}
#ifndef putchar
int putchar(char ch)
{
asm (ch) -> int { syscall putchar; };
}
#endif
#ifndef getchar
int getchar()
{
asm () -> int { syscall getchar; };
}
#endif
int printf(char* format, ...)
{
unsigned int ch_written = 0;
unsigned int var_arg_idx = 1;
// For each character of the format string
for (unsigned int i = 0;; ++i)
{
char c = format[i];
if (c == 0)
{
break;
}
// Format specifier
if (c == '%')
{
// Percent character
if (format[i+1] == '%')
{
putchar('%');
++i;
++ch_written;
continue;
}
// String
if (format[i+1] == 's')
{
++i;
// Get the integer argument and print it
asm (var_arg_idx) -> void {
get_var_arg;
syscall print_str;
};
++var_arg_idx;
continue;
}
// Signed decimal integer
if (format[i+1] == 'd' || format[i+1] == 'i')
{
++i;
// Get the integer argument and print it
asm (var_arg_idx) -> void {
get_var_arg;
trunc_u32;
sx_i32_i64;
syscall print_i64;
};
++var_arg_idx;
continue;
}
// Unsigned decimal integer
if (format[i+1] == 'u')
{
++i;
// Get the integer argument and print it
asm (var_arg_idx) -> void {
get_var_arg;
trunc_u32;
syscall print_i64;
};
++var_arg_idx;
continue;
}
// TODO: %x %X for printing hexadecimal integers
// TODO: %p for printing pointers
// Floats (f32)
if (format[i+1] == 'f')
{
++i;
// Get the float argument and print it
asm (var_arg_idx) -> void {
get_var_arg;
syscall print_f32;
};
++var_arg_idx;
continue;
}
// Unknown format specifier
// Just print it in the output for now
// That makes it easier to debug the problem than a panic.
}
// Print this character
// NOTE: may want to be careful about printing
// in the middle of a UTF-8 unicode character?
putchar(c);
++ch_written;
}
// Return total number of chars written
return ch_written;
}
#endif