forked from jpoirier/picoc
-
Notifications
You must be signed in to change notification settings - Fork 4
/
clibrary.c
137 lines (126 loc) · 3.83 KB
/
clibrary.c
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
/* */
#include "picoc.h"
#include "interpreter.h"
/* endian-ness checking */
static const int __ENDIAN_CHECK__ = 1;
static int BigEndian;
static int LittleEndian;
/* global initialisation for libraries */
void LibraryInit(Picoc *pc)
{
/* define the version number macro */
pc->VersionString = TableStrRegister(pc, PICOC_VERSION);
VariableDefinePlatformVar(pc, NULL, "PICOC_VERSION", pc->CharPtrType,
(union AnyValue*)&pc->VersionString, false);
/* define endian-ness macros */
BigEndian = ((*(char*)&__ENDIAN_CHECK__) == 0);
LittleEndian = ((*(char*)&__ENDIAN_CHECK__) == 1);
VariableDefinePlatformVar(pc, NULL, "BIG_ENDIAN", &pc->IntType,
(union AnyValue*)&BigEndian, false);
VariableDefinePlatformVar(pc, NULL, "LITTLE_ENDIAN", &pc->IntType,
(union AnyValue*)&LittleEndian, false);
}
/* add a library */
void LibraryAdd(Picoc *pc, struct LibraryFunction *FuncList)
{
struct ParseState Parser;
int Count;
char *Identifier;
struct ValueType *ReturnType;
struct Value *NewValue;
void *Tokens;
char *IntrinsicName = TableStrRegister(pc, "c library");
/* read all the library definitions */
for (Count = 0; FuncList[Count].Prototype != NULL; Count++) {
Tokens = LexAnalyse(pc,
(const char*)IntrinsicName, FuncList[Count].Prototype,
strlen((char*)FuncList[Count].Prototype), NULL);
LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens,
IntrinsicName, true, false);
TypeParse(&Parser, &ReturnType, &Identifier, NULL, NULL, NULL);
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func;
HeapFreeMem(pc, Tokens);
}
}
/* print a type to a stream without using printf/sprintf */
void PrintType(struct ValueType *Typ, IOFILE *Stream)
{
switch (Typ->Base) {
case TypeVoid:
PrintStr("void", Stream);
break;
case TypeInt:
PrintStr("int", Stream);
break;
case TypeShort:
PrintStr("short", Stream);
break;
case TypeChar:
PrintStr("char", Stream);
break;
case TypeLong:
PrintStr("long", Stream);
break;
case TypeLongLong:
PrintStr("long long", Stream);
break;
case TypeUnsignedInt:
PrintStr("unsigned int", Stream);
break;
case TypeUnsignedShort:
PrintStr("unsigned short", Stream);
break;
case TypeUnsignedLong:
PrintStr("unsigned long", Stream);
break;
case TypeUnsignedLongLong:
PrintStr("unsigned long long", Stream);
break;
case TypeUnsignedChar:
PrintStr("unsigned char", Stream);
break;
case TypeFloat:
PrintStr("float", Stream);
break;
case TypeDouble:
PrintStr("double", Stream);
break;
case TypeFunction:
PrintStr("function", Stream);
break;
case TypeMacro:
PrintStr("macro", Stream);
break;
case TypePointer:
if (Typ->FromType)
PrintType(Typ->FromType, Stream);
PrintCh('*', Stream);
break;
case TypeArray:
PrintType(Typ->FromType, Stream);
PrintCh('[', Stream);
if (Typ->ArraySize != 0)
PrintSimpleInt(Typ->ArraySize, Stream);
PrintCh(']', Stream);
break;
case TypeStruct:
PrintStr("struct ", Stream);
PrintStr(Typ->Identifier, Stream);
break;
case TypeUnion:
PrintStr("union ", Stream);
PrintStr(Typ->Identifier, Stream);
break;
case TypeEnum:
PrintStr("enum ", Stream);
PrintStr(Typ->Identifier, Stream);
break;
case TypeGotoLabel:
PrintStr("goto label ", Stream);
break;
case Type_Type:
PrintStr("type ", Stream);
break;
}
}