fb-doc  0.4.0
FreeBASIC documentation tool
fbdoc_emit_csource.bas
Go to the documentation of this file.
1 
16 
17 #INCLUDE ONCE "fbdoc_options.bi"
18 #INCLUDE ONCE "fbdoc_emit_lfn.bi"
19 
20 
21 
22 DIM SHARED AS STRING LOFN
23 
24 
25 
32 SUB c_CTOR CDECL(BYVAL O AS Options PTR)
33  VAR fnr = FREEFILE
34  IF OPEN(LFN_FILE FOR INPUT AS #fnr) THEN EXIT SUB
35  MSG_LINE(LFN_FILE)
36  LOFN = STRING(LOF(fnr), 0)
37  GET #fnr, , LOFN
38  CLOSE #fnr
39  MSG_CONT("loaded")
40 END SUB
41 
42 
43 
50 SUB c_Init CDECL(BYVAL P AS Parser PTR)
51  P->SrcBgn = 0
52 END SUB
53 
54 
55 
62 SUB c_exit CDECL(BYVAL P AS Parser PTR)
63  emit_comments(P, P->Fin)
64 END SUB
65 
66 
67 
77 SUB c_include CDECL(BYVAL P AS Parser PTR)
78  WITH *P '&Parser* P;
79  emit_comments(P, .Tk1[1])
80  VAR fnam = .SubStr(.NamTok)
81  IF OPT->Types = OPT->C_STYLE THEN
82  VAR i = INSTRREV(fnam, ".")
83  Code("#include " & LEFT(fnam, i))
84  IF LCASE(RIGHT(fnam, 4)) = ".bi""" THEN Code("h""") ELSE Code("c""")
85  ELSE
86  Code("#include " & fnam)
87  END IF
88  IF OPT->InTree THEN .Include(TRIM(fnam, """"))
89  END WITH
90 END SUB
91 
92 
93 
101 SUB c_defi_ CDECL(BYVAL P AS Parser PTR)
102  WITH *P '&Parser* P;
103  emit_comments(P, .Tk1[1])
104 
105  Code("#define ")
106  VAR e = .EndTok[1]
107  IF *.StaTok = .TOK_MACR THEN
108  VAR a = .NamTok[1], l = .CurTok[1] - a
109  Code(MID(.Buf, a + 1, l) & " /* (multi line FreeBASIC #MACRO) ")
110  a += l
111  Code(MID(.Buf, a + 1, e - a) & " */ ")
112  ELSE
113  VAR a = .NamTok[1], l = .DivTok[-2] + .DivTok[-1] - a
114  Code(MID(.Buf, a + 1, l))
115  a += l
116  l = e - a
117  IF l > 0 THEN Code(" /* " & MID(.Buf, a + 1, e - a) & " */")
118  END IF
119  .SrcBgn = e
120  END WITH
121 END SUB
122 
123 
124 
134 SUB c_func_ CDECL(BYVAL P AS Parser PTR) ' ToDo: internal function calls for diagrams
135  WITH *P '&Parser* P;
136  var futo = .FunTok, nato = .NamTok
137  emit_comments(P, .Tk1[1])
138 
139  OPT->CreateFunction(P)
140  Code(" {")
141 
142  IF LEN(LOFN) THEN
143  'VAR cfl = .TOK_CTOR = *futo ORELSE _
144  '.TOK_DTOR = *futo ORELSE _
145  '.TOK_DOT = nato[3]
146  VAR cna = UCASE(.SubStr(nato)) _
147  , wtype = "" _
148  , t = .CurTok _
149  , e = .EndTok - 6
150  WHILE t < e
151  SELECT CASE AS CONST *t
152  CASE .TOK_END
153  t += 3
154  IF *t = .TOK_WITH THEN wtype = ""
155  CASE .TOK_WITH
156  VAR p = t[1] + t[2]
157  t += 3
158  WHILE t < e
159  IF *t > .TOK_EOS andalso *t < .TOK_COMSL THEN t += 3 ELSE EXIT WHILE
160  WEND
161  wtype = TRIM(MID(.Buf, p + 2, *(t-2) + *(t-1) - p - 1))
162  IF wtype[0] = ASC("*") THEN wtype = MID(wtype, 2) & "->" ELSE wtype &= "."
163  CASE .TOK_BROPN
164  VAR a = *(t - 2) _
165  , l = *(t - 1) _
166  , g = 0
167  FOR i AS INTEGER = LEN(LOFN) - 2 TO 0 STEP -1
168  VAR x = a + l - 1
169  WHILE (.Buf[x] AND &b11011111) = (LOFN[i] AND &b11011111)
170  i -= 1
171  x -= 1
172  IF x < a THEN ' end of source word
173  VAR tt = t - 6
174  SELECT CASE AS CONST LOFN[i]
175  CASE ASC(LFN_SEP) : g = 0 : x += 2 ' global function `symbol()`
176  CASE ASC(".") ' member function `udtname.symbol()`
177  IF .Buf[x] = ASC(".") ORELSE .Buf[x] = ASC(">") THEN ' chain of one or more member functions
178  WHILE tt > .Tk1
179  IF *tt = .TOK_MEOP ORELSE *tt = .TOK_DOT _
180  THEN tt -= 3 ELSE tt += 3 : x = tt[1] + 1 : g = 0 : EXIT WHILE ' `symbol.symbol()`, `symbol->symbol()`
181  IF .Buf[tt[4] - 1] < ASC("A") THEN tt += 3 : x = tt[1] + 2 : g = 1 : EXIT WHILE ' .symbol()
182  IF *tt = .TOK_WORD THEN tt -= 3 ELSE tt += 6 : x = tt[1] + 1 : g = 1 : EXIT WHILE ' .symbol()
183  WEND
184  l += a - x + 1
185  ELSE ' no chain, just a single name
186  'IF 0 = cfl THEN EXIT WHILE
187  VAR z = i : i = INSTRREV(LOFN, LFN_SEP, z)
188  IF cna <> UCASE(MID(LOFN, i + 1, z - i)) THEN
189 'MSG_LINE(cna & " / " & MID(LOFN, i + 1, z - i) & " / " & MID(LOFN, z + 2, l))
190  if MID(LOFN, i + 1, z - i) <> MID(LOFN, z + 2, l) then EXIT WHILE
191  g = 1 : x += 2 : wtype = MID(.Buf, z, l) & "." ' CTOR
192  else
193  g = 0 : x += 2
194  END IF
195  END IF
196  CASE ELSE : EXIT WHILE ' no match
197  END SELECT
198  emit_comments(P, a)
199  IF g THEN Code(" " & wtype & MID(.Buf, x, l) & "();") _
200  ELSE Code(" " & MID(.Buf, x, l) & "();")
201  EXIT FOR
202  END IF
203  WEND
204 
205  WHILE i > 0 ANDALSO LOFN[i] <> ASC(LFN_SEP) : i -= 1 : WEND
206  NEXT
207  END SELECT : t += 3
208  WEND
209  END IF
210 
211  emit_comments(P, .EndTok[1] - 1)
212  Code("};")
213  END WITH
214 END SUB
215 
216 
217 
229 SUB c_decl_ CDECL(BYVAL P AS Parser PTR)
230  WITH *P '&Parser* P;
231  emit_comments(P, .Tk1[1])
232 
233  IF 0 = .ListCount THEN
234  SELECT CASE AS CONST *.StaTok
235  CASE .TOK_CONS : Code("const ")
236  CASE .TOK_STAT : Code("static ")
237  CASE .TOK_COMM : Code("common ")
238  CASE .TOK_EXRN : Code("extern ")
239  CASE .TOK_TYPE : Code("typedef ")
240  IF 0 = .FunTok ANDALSO .TypTok > .NamTok THEN Code("struct ")
241  END SELECT
242  END IF
243 
244  IF .FunTok THEN : OPT->CreateFunction(P)
245  ELSEIF .TypTok THEN : OPT->CreateVariable(P)
246  ELSE
247  IF 0 = .ListCount THEN Code("VAR ")
248  Code(.SubStr(.NamTok))
249  IF .BitTok THEN Code(.BitIni)
250  IF .IniTok THEN CreateIni(P)
251  END IF
252  IF *.CurTok <= .TOK_EOS THEN Code(";") : EXIT SUB
253  IF .NamTok > .TypTok _
254  THEN Code(", ") _
255  ELSE Code("; ")
256  END WITH
257 END SUB
258 
259 
260 DECLARE SUB c_Block CDECL(BYVAL AS Parser PTR)
261 
262 
270 SUB cEntryBlockENUM CDECL(BYVAL P AS Parser PTR)
271  WITH *P '&Parser* P;
272  emit_comments(P, .Tk1[1])
273 
274  IF 0 = .ListCount THEN Code(STRING(.LevelCount * 2, " "))
275  Code(.SubStr(.NamTok))
276  IF .IniTok THEN CreateIni(P)
277  IF *.CurTok <> .TOK_END THEN Code(", ")
278  END WITH
279 END SUB
280 
281 
282 
290 SUB cEntryBlockTypeUnion CDECL(BYVAL P AS Parser PTR)
291  WITH *P '&Parser* P;
292  emit_comments(P, .Tk1[1])
293 
294  SELECT CASE AS CONST *.Tk1
295  CASE .TOK_PRIV : Code("private:")
296  CASE .TOK_PROT : Code("protected:")
297  CASE .TOK_PUBL : Code("public:")
298  CASE .TOK_ENUM, .TOK_UNIO, .TOK_TYPE, .TOK_CLAS : c_Block(P)
299  CASE ELSE
300  IF 0 = .ListCount THEN Code(STRING(.LevelCount * 2, " "))
301  IF *.Tk1 = .TOK_DECL THEN OPT->CreateFunction(P) : Code(";") : EXIT SUB
302  IF .FunTok THEN OPT->CreateFunction(P) _
303  ELSE OPT->CreateVariable(P)
304  IF *.CurTok <= .TOK_EOS THEN Code(";") : EXIT SUB
305  IF .NamTok > .TypTok THEN Code(",") ELSE Code("; ")
306  END SELECT
307  END WITH
308 END SUB
309 
310 
311 
321 SUB c_Block CDECL(BYVAL P AS Parser PTR)
322  WITH *P '&Parser* P;
323  emit_comments(P, .Tk1[1])
324 
325  IF .LevelCount THEN Code(STRING(.LevelCount * 2, " "))
326  SELECT CASE AS CONST IIF(.LevelCount, *.Tk1, *.StaTok)
327  CASE .TOK_TYPE, .TOK_CLAS
328  IF OPT->Types = OPT->FB_STYLE THEN
329  Code("class " & .BlockNam)
330  VAR t = .Tk1 + 3
331  IF *t = .TOK_EXDS THEN Code(" : public " & .SubStr(t + 3)) ' ToDo: parse list of names
332  Code("{ public:")
334  .BlockNam = ""
335  ELSE
336  IF 0 = .LevelCount ANDALSO LEN(.BlockNam) THEN Code("typedef ")
337  Code("struct " & .BlockNam & "{")
339  END IF
340  CASE .TOK_UNIO
341  IF 0 = .LevelCount ANDALSO LEN(.BlockNam) THEN Code("typedef ")
342  Code("union " & .BlockNam & "{")
344  CASE .TOK_ENUM
345  IF 0 = .LevelCount ANDALSO LEN(.BlockNam) THEN Code("typedef ")
346  Code("enum " & .BlockNam & "{")
348  CASE ELSE : Code("-???-")
349  END SELECT
350 
351  emit_comments(P, .Tk1[1])
352  IF .LevelCount THEN Code(STRING(.LevelCount * 2, " "))
353  Code("};")
354  END WITH
355 END SUB
356 
357 
358 
365 SUB init_csource(byval Emi as EmitterIF PTR)
366  WITH *Emi
367  .Error_ = @emit_error()
368 
369  .Defi_ = @c_defi_()
370  .Incl_ = @c_include()
371  .Func_ = @c_func_()
372  .Decl_ = @c_decl_()
373  .Enum_ = @c_Block()
374  .Unio_ = @c_Block()
375  .Clas_ = @c_Block()
376 
377  .Init_ = @c_Init()
378  .Exit_ = @c_exit()
379  .CTOR_ = @c_CTOR()
380  END WITH
381 END SUB
382 
383 
384