Initial Revision
[ohcount] / ext / ohcount_native / generator.rb
1 require 'state'
2 require 'transition'
3 require 'escape_helper'
4
5 # So that monoglot and polyglot source files can easily require eachother
6 $LOAD_PATH << File.join(File.dirname(__FILE__), 'glots')
7
8 # Load all monoglots and polyglots
9 Dir.glob(File.join(File.dirname(__FILE__), 'glots/*.rb')).each {|f| require f }
10
11 module Ohcount
12         class Generator
13                 include EscapeHelper
14
15                 # The code generator that produces the 'polyglots.c' source file, which contains
16                 # definitions for all the language states and transitions.
17                 def generate
18
19                         # Defines all of the monoglots and polyglots known to the parser.
20                         ada = CMonoglot.new("ada",                 '--',             nil,                true,  false)
21                         assembler = CMonoglot.new("assembler",     [';', '!', '//'], [e('/*'), e('*/')], false, false)
22                         awk = CMonoglot.new("awk",                 '#',              nil,                true,  false, {:no_escape_dquote => true})
23                         bat = LineCommentMonoglot.new("bat",        '^\\\\s*(?i)REM(?-i)')
24                         boo = PythonMonoglot.new("boo")
25                         clearsilver = CMonoglot.new("clearsilver", '#',              nil,                true,  true)
26                         cncpp = CMonoglot.new("cncpp",             '//',             [e('/*'), e('*/')], true,  false)
27                         csharp = CMonoglot.new("csharp",           '//',             [e('/*'), e('*/')], true,  false)
28                         css = CMonoglot.new("css",                  nil,             [e('/*'), e('*/')], false,  false)
29                         dylan = CMonoglot.new("dylan",             '//',             nil,                true,  false)
30                         erlang = CMonoglot.new("erlang",           '%%',             nil,                true,  true)
31                         java = CMonoglot.new("java",               '//',             [e('/*'), e('*/')], true,  false)
32                         javascript = CMonoglot.new("javascript",   '//',             [e('/*'), e('*/')], true,  true)
33                         emacslisp = LineCommentMonoglot.new("emacslisp", ";")
34                         lisp = LineCommentMonoglot.new("lisp", ";")
35                         lua = CMonoglot.new("lua",                 '--',             nil,                true,  true)
36                         matlab = CMonoglot.new("matlab",           '#|%',            ['{%', '%}'], false,true)
37                         objective_c = CMonoglot.new("objective_c", '//',             [e('/*'), e('*/')], true,  false)
38                         pascal = CMonoglot.new("pascal",           '//',             ['{','}'],          true,  false)
39                         perl = CMonoglot.new("perl",               '#',              nil,                true,  true)
40                         phplanguage = CMonoglot.new("php",         '//',             [e('/*'), e('*/')], true,  true, {:polyglot_name => 'phplanguage'})
41                         python = PythonMonoglot.new("python")
42                         ruby = CMonoglot.new("ruby",               '#',              nil,                true,  true)
43                         rexx = CMonoglot.new("rexx",               nil,              [e('/*'), e('*/')], true,  true)
44                         scheme = LineCommentMonoglot.new("scheme", ";")
45                         shell = CMonoglot.new("shell",             '#',              nil,                false, false)
46                         sql = CMonoglot.new("sql",                 ['--','//'],      [['{','}'], [e('/*'), e('*/')]], true, true)
47                         tcl = CMonoglot.new("tcl",                 '#',              nil,                true,  false)
48                         visualbasic = CMonoglot.new("visualbasic", '\'',             nil,                true,  false)
49                         xml = XmlMonoglot.new("xml")
50                         html = HtmlPolyglot.new("html", javascript, css)
51                         php = HtmlWithPhpPolyglot.new("php", html, phplanguage)
52                         rhtml = RhtmlPolyglot.new("rhtml", html, ruby)
53                         jsp = JspPolyglot.new("jsp", html, java)
54                         groovy = CMonoglot.new("groovy",           '//',             [e('/*'), e('*/')], true,  false)
55                         clearsilver_template = ClearsilverTemplate.new("clearsilver_template", html, clearsilver)
56                         dmd = DMonoglot.new('dmd')
57
58                         polyglots = [
59                                 ada ,
60                                 assembler ,
61                                 awk ,
62                                 bat ,
63                                 boo ,
64                                 clearsilver ,
65                                 cncpp ,
66                                 csharp ,
67                                 css ,
68                                 dylan ,
69                                 erlang ,
70                                 groovy ,
71                                 java ,
72                                 javascript ,
73                                 emacslisp ,
74                                 lisp ,
75                                 lua ,
76                                 matlab,
77                                 objective_c,
78                                 pascal ,
79                                 perl ,
80                                 phplanguage ,
81                                 python ,
82                                 ruby ,
83                                 rexx ,
84                                 scheme ,
85                                 shell ,
86                                 sql ,
87                                 tcl ,
88                                 visualbasic ,
89                                 xml ,
90                                 dmd ,
91
92                                 # poly
93                                 html,
94                                 php,
95                                 rhtml,
96                                 jsp,
97                                 clearsilver_template
98                         ]
99                         File.open("polyglots.c", "w") do |io|
100
101                                 # spit out the preamble to our source code
102                                 io.puts <<PREAMBLE
103 /*
104  * polyglots.c
105  * Ohcount
106  *
107  * GENERATED FILE **DO NOT EDIT**
108  *
109  */
110
111 #define __polyglots_c__
112 #include "common.h"
113
114 #define RETURN (State *)NULL
115 PREAMBLE
116
117                                 # spits out the actual POLYGLOTS array, which contains a reference to all the polyglots we define in our library
118                                 polyglots.each do |p|
119                                         p.print(io)
120                                 end
121                                 io.puts "\n"
122                                 Monoglot::print_banner(io, "POLYGLOTS")
123                                 io.puts "Polyglot *POLYGLOTS[] = {"
124                                 polyglots.each do |p|
125                                         io.puts "       &#{ p.definition },"
126                                 end
127                                 io.puts "       NULL\n};"
128                         end
129                 end
130         end
131 end
132
133 Ohcount::Generator.new.generate