SpiderScript - Huge changes to introduce bytecode support
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / bytecode_makefile.c
1 /*
2  * SpiderScript Library
3  * by John Hodge (thePowersGang)
4  * 
5  * bytecode_makefile.c
6  * - Generate a bytecode file
7  */
8 #include <stdlib.h>
9 #include "ast.h"
10 #include "bytecode_gen.h"
11 #include <stdio.h>
12 #include <string.h>
13
14 // === IMPORTS ===
15
16 // === PROTOTYPES ===
17
18 // === GLOBALS ===
19
20 // === CODE ===
21 int Bytecode_ConvertScript(tSpiderScript *Script, const char *DestFile)
22 {
23         tStringList     strings = {0};
24         tAST_Function   *fcn;
25         FILE    *fp;
26          int    fcn_hdr_offset = 0;
27          int    fcn_count = 0;
28          int    strtab_ofs;
29
30         void _put8(uint8_t val)
31         {
32                 fwrite(&val, 1, 1, fp);
33         }
34         void _put32(uint32_t val)
35         {
36                 _put8(val & 0xFF);
37                 _put8(val >> 8);
38                 _put8(val >> 16);
39                 _put8(val >> 24);
40         }
41
42         fp = fopen(DestFile, "wb");
43         if(!fp) return 1;
44         
45         // Create header
46         fwrite("SSBC\r\n\xBC\x55", 8, 1, fp);
47         _put32(0);      // Function count, to be filled
48         _put32(0);      // String count
49         _put32(0);      // String table offset
50         // TODO: Variant info
51
52         fcn_hdr_offset = ftell(fp);
53
54         // Create function descriptors
55         for(fcn = Script->Script->Functions; fcn; fcn = fcn->Next, fcn_count ++)
56         {
57                 tAST_Node *arg;
58
59                 _put32( StringList_GetString(&strings, fcn->Name, strlen(fcn->Name)) );
60                 _put32( 0 );    // Code offset
61                 _put8( fcn->ReturnType );
62                 
63                 if(fcn->ArgumentCount > 255) {
64                         // ERROR: Too many args
65                         return 2;
66                 }
67                 _put8( fcn->ArgumentCount );
68
69                 // Argument types?
70                 for(arg = fcn->Arguments; arg; arg = arg->NextSibling)
71                 {
72                         _put32( StringList_GetString(&strings, arg->DefVar.Name, strlen(arg->DefVar.Name)) );
73                         _put8( arg->DefVar.DataType );
74                 }
75         }
76
77         // Put function code in
78         for(fcn = Script->Script->Functions; fcn; fcn = fcn->Next)
79         {
80                 char    *code;
81                  int    len, code_pos;
82                 tBC_Function    *bc_fcn;
83         
84                 // Fix header   
85                 code_pos = ftell(fp);
86                 fseek(fp, SEEK_SET, fcn_hdr_offset + 4);
87                 _put32( code_pos );
88                 fseek(fp, SEEK_SET, code_pos );
89
90                 fcn_hdr_offset += 4+4+1+1+(4+1)*fcn->ArgumentCount;
91                 
92                 // Write code
93                 bc_fcn = Bytecode_ConvertFunction(fcn);
94                 code = Bytecode_SerialiseFunction(bc_fcn, &len, &strings);
95                 Bytecode_DeleteFunction(bc_fcn);
96                 fwrite(code, len, 1, fp);
97         }
98
99         // String table
100         strtab_ofs = ftell(fp);
101         {
102                  int    string_offset = strtab_ofs + (4+4)*strings.Count;
103                 tString *str;
104                 // Array
105                 for(str = strings.Head; str; str = str->Next)
106                 {
107                         _put32(str->Length);
108                         _put32(string_offset);
109                         string_offset += str->Length + 1;
110                 }
111                 // Data
112                 for(str = strings.Head; str; str = str->Next)
113                 {
114                         fwrite(str->Data, str->Length, 1, fp);
115                         _put8(0);
116                 }
117         }
118
119         // Fix header
120         fseek(fp, 8, SEEK_SET);
121         _put32(fcn_count);
122         _put32(strings.Count);
123         _put32(strtab_ofs);
124
125         return 0;
126 }
127

UCC git Repository :: git.ucc.asn.au