rubymacros 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,16 @@
1
- === 0.1.2 / 2009-04-26
1
+ === 0.1.4 / 2009-05-21
2
+ * 1 Major Enhancement:
3
+ * line numbers are now preserved in preprocessed code;
4
+ * backtraces should make more sense.
5
+ * 1 Minor Enhancement:
6
+ * updated to keep in sync with the latest RedParse api (sigh)
7
+
8
+ === 0.1.3 / 2009-05-02
9
+ * 1 Minor Enhancement:
10
+ * depend on redparse>=0.8.1, since 0.8.0 had a stupid permission problem
2
11
 
3
- * 7 minor enhancements
12
+ === 0.1.2 / 2009-04-26
13
+ * 7 Minor Enhancements
4
14
  * lots of nice comments added, thanks to Paul Brannan and Tatsuji Kawai
5
15
  * Paul fixed the weird rdoc failure too!
6
16
  * incorrect warning removed
@@ -10,7 +20,6 @@
10
20
  * all files should be world-readable now
11
21
 
12
22
  === 0.1.0 / 2008-10-24
13
-
14
- * 1 major enhancement
23
+ * 1 Major Enhancement
15
24
  * Birthday!
16
25
 
@@ -2,7 +2,6 @@ COPYING.LGPL
2
2
  Manifest.txt
3
3
  README.txt
4
4
  History.txt
5
- rubymacros.vpj
6
5
  Rakefile
7
6
  test/test_form.rb
8
7
  test/test_expand.rb
@@ -23,3 +22,7 @@ example/with_wrap.rb
23
22
  example/linenum.rb
24
23
  example/linenum_user.rb
25
24
  example/linenum_wrap.rb
25
+ example/andand_wrap.rb
26
+ lib/weakkeyhash.rb
27
+ test/test_all.rb
28
+ TODO
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  = RubyMacros
2
- * http://rubymacros.rubyforge.org
3
2
  * http://rubyforge.org/projects/rubymacros
3
+ * http://github.com/coatl/rubymacros
4
4
 
5
5
  == DESCRIPTION:
6
6
  RubyMacros is a lisp-like macro pre-processor for Ruby. More than just a
@@ -32,7 +32,6 @@ a proof of concept or toy at this point:
32
32
  * some ruby syntax is unsupported in files using macros
33
33
  * files using macros must be loaded via Macro.require;
34
34
  * Kernel#require will not recognize macros
35
- * RedParse Node tree format will be changing slightly
36
35
  * macros cannot be scoped
37
36
  * no variable (or other) hygiene
38
37
 
@@ -95,10 +94,12 @@ macro callsite in the parsetree which contained it.
95
94
 
96
95
 
97
96
  == Known Problems
98
- * need to insert extra parens around form params and macro texts
97
+ * need to insert extra parens around form params
99
98
  * a variety of parsetrees are kept around forever for no good reason
100
- * a few warnings and disabled tests in unit tests
101
- * however, huge rediculous piles of RedParse warnings when running 'rake test'
99
+ * a few disabled tests in unit tests
100
+ * =begin...=end in forms causes minor unit test failures
101
+ * unterminated string in forms is not handled well
102
+
102
103
 
103
104
  == License:
104
105
  Copyright (C) 2008 Caleb Clausen
data/Rakefile CHANGED
@@ -2,7 +2,6 @@
2
2
  # Distributed under the terms of Ruby's license.
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
- require 'lib/macro/version.rb'
6
5
 
7
6
 
8
7
  if $*==["test"]
@@ -16,6 +15,8 @@ if $*==["test"]
16
15
  exit
17
16
  end
18
17
 
18
+ require 'lib/macro/version.rb'
19
+
19
20
  readme=open("README.txt")
20
21
  readme.readline("\n== DESCRIPTION:")
21
22
  readme.readline("\n\n")
@@ -24,8 +25,8 @@ end
24
25
  hoe=Hoe.new("rubymacros", Macro::VERSION) do |_|
25
26
  _.author = "Caleb Clausen"
26
27
  _.email = "rubymacros-owner @at@ inforadical .dot. net"
27
- _.url = ["http://rubymacros.rubyforge.org/", "http://rubyforge.org/projects/rubymacros/"]
28
- _.extra_deps << ['redparse', '>= 0.8.1']
28
+ _.url = ["http://github.com/coatl/rubymacros/", "http://rubyforge.org/projects/rubymacros/"]
29
+ _.extra_deps << ['redparse', '>= 0.8.2']
29
30
  _.test_globs=["test/*"]
30
31
  _.description=desc
31
32
  _.summary=desc[/\A[^.]+\./]
data/TODO ADDED
@@ -0,0 +1,35 @@
1
+ macro options
2
+ immediate vs delayed
3
+ 'protected' vs unprotected macros -- params and result surrounded by ()
4
+ precedence for operator macros
5
+ hygienic vs unhygienic
6
+
7
+ static selector namespaces?
8
+
9
+ other types of macro:
10
+ replacement by example -- block style
11
+ replacement by example -- form with matchers in form escapes
12
+ straight out Reg::Transform expression as macro
13
+ operator macros
14
+ lmacros
15
+
16
+ parser extensions to make the language more macro-friendly:
17
+ dynamically named callsites: rcvr.( a<b ? :foo : :bar )(args)
18
+ dynamically named constant lookups: Parent::(whatever)
19
+ arbitrary expression in block slot of callsite:
20
+ foo.bar(args)block
21
+ foo.bar(args)bl.ock
22
+ foo.bar(args)(...whatever)
23
+ (but don't allow funny characters here (unless parenthesised))
24
+ block literals. empty block is {||}
25
+ else block and hash disambiguated by presence of => or :
26
+ dynamic method names?: def (expr returning name); ... end
27
+
28
+
29
+ cool macros to write:
30
+ ,, -- evaluates left and right sides then returns val of LEFT
31
+ .? -- call a method if rcvr respond_to? it
32
+ {<..>} -- ordered hash
33
+ trace_subexpressions() -- print val of each subexpression
34
+ better assert
35
+ iter
@@ -1,3 +1,10 @@
1
1
  macro andand(a,b)
2
2
  :(^a and ^b)
3
3
  end
4
+
5
+ def main
6
+ andand(false,puts("FAILED!!!"))
7
+ andand(true,puts("Success!"))
8
+ end
9
+
10
+ main #if $0==__FILE__
@@ -0,0 +1,2 @@
1
+ require "macro"
2
+ Macro.require "example/andand"
@@ -4,8 +4,8 @@ if $Debug
4
4
  macro assert(cond)
5
5
  if RedParse::OpNode===cond and /\A[=!]=\Z/===cond.op
6
6
  left,op,right=*cond
7
- :(fail 'expected '+^left.unparse({})+"(==#{^left}) to be "+
8
- ^op+" "+^right.unparse({})+"(==#{^right})" unless ^cond)
7
+ :(fail 'expected '+^left.unparse+"(==#{^left}) to be "+
8
+ ^op+" "+^right.unparse+"(==#{^right})" unless ^cond)
9
9
  else
10
10
  :(fail "expected #{:(^^cond)}, but was not true" unless ^cond)
11
11
  end
@@ -24,7 +24,7 @@ require 'redparse'
24
24
  require "macro/form"
25
25
  require "macro/version"
26
26
 
27
- warn "need to insert extra parens around form params and macro texts"
27
+ warn "need to insert extra parens around form params"
28
28
 
29
29
  class Object # :nodoc:
30
30
  #as close as I can get to an empty binding (used below in Macro.eval)
@@ -168,7 +168,7 @@ class Macro
168
168
  result={}
169
169
  seen[obj.__id__]=result
170
170
  obj.each_pair{|k,v|
171
- result[copy k]=copy v,seen
171
+ result[copy( k )]=copy v,seen
172
172
  }
173
173
  result
174
174
  when Module,Proc,IO,Method,
@@ -209,9 +209,9 @@ class Macro
209
209
  modpath=ConstantNode[nil,*session[:@modpath]]
210
210
  modpath.push "Object" unless modpath.size>1
211
211
  if session[:@namespace_type]==ModuleNode
212
- node=ModuleNode[modpath,node] #:(module ^modpath; ^node; end)
212
+ node=ModuleNode[modpath,node,[],nil,nil] #:(module ^modpath; ^node; end)
213
213
  else
214
- node=ClassNode[modpath,nil,node] #:(class ^modpath; ^node; end)
214
+ node=ClassNode[modpath,nil,node,[],nil,nil] #:(class ^modpath; ^node; end)
215
215
  end
216
216
  end
217
217
 
@@ -228,7 +228,7 @@ class Macro
228
228
  [unexpanded, ConstantNode[nil,"Macro","GLOBALS"],
229
229
  HashLiteralNode[LiteralNode[:@expand_in_defs], VarLikeNode["true"]], Macro.quote(filename)],
230
230
  nil,nil]
231
- return CallNode[expanded,evalname,[Macro.quote filename],nil,nil]
231
+ return CallNode[expanded,evalname,[Macro.quote( filename )],nil,nil]
232
232
  end
233
233
 
234
234
  class Node
@@ -257,7 +257,7 @@ class Macro
257
257
 
258
258
  expanded_tree=self #Macro.expand(deep_copy,::Macro::GLOBALS)
259
259
 
260
- unparsed=expanded_tree.unparse({})
260
+ unparsed=expanded_tree.unparse
261
261
  #puts unparsed
262
262
  ::Kernel.eval unparsed, binding||::Object.new_binding,file||'(eval)',line||1
263
263
  end
@@ -286,7 +286,7 @@ class Macro
286
286
  true
287
287
  }
288
288
 
289
- unparsed=expanded_tree.unparse({})
289
+ unparsed=expanded_tree.unparse
290
290
  #p expanded_tree
291
291
  #puts unparsed
292
292
  Tempfile.open("macroexpanded_"+name.gsub("/","__")){|tf|
@@ -480,8 +480,8 @@ class Macro
480
480
 
481
481
  # and keep recursing, no matter what, by all means!!
482
482
  newnode=Macro.expand newnode,macros,session #just do it here
483
- return newnode,false #and not in caller
484
-
483
+ newnode=OneLineParenedNode[newnode] #disable newlines in macro text
484
+ return newnode,false #and not in caller
485
485
  end
486
486
  end
487
487
 
@@ -529,7 +529,14 @@ class Macro
529
529
  end
530
530
  session[:@modpath].push *name
531
531
 
532
- map!{|n| Macro.expand(n,macros,session) if n}
532
+ map!{|n|
533
+ case n
534
+ when nil
535
+ when Node; Macro.expand(n,macros,session)
536
+ when Array; n.map!{|nn| Macro.expand(nn,macros,session) }
537
+ else fail
538
+ end
539
+ }
533
540
 
534
541
  if old_modpath
535
542
  session[:@modpath]=old_modpath
@@ -610,7 +617,7 @@ class Macro
610
617
  carets+=1
611
618
  end
612
619
  if carets==nest
613
- return node.unparse({})
620
+ return node.unparse
614
621
  else
615
622
  return super
616
623
  end
@@ -646,7 +653,7 @@ class Macro
646
653
  #
647
654
  # +o+:: a list of options for unparse
648
655
  #
649
- def unparse o
656
+ def unparse o=default_unparse_options
650
657
  result="macro "
651
658
  result+=receiver.unparse(o)+'.' if receiver
652
659
  result+=name
@@ -655,12 +662,23 @@ class Macro
655
662
  result+=args.map{|arg| arg.unparse o}.join','
656
663
  result+=")"
657
664
  end
658
- result+="\n"
659
- result+=body.unparse(o) if body
665
+ result+=unparse_nl(body,o)+body.unparse(o) if body
660
666
  result+=rescues.map{|resc| resc.unparse o}.to_s
661
- result+="else "+else_.unparse( o )+"\n" if else_
662
- result+="ensure "+ensure_.unparse( o )+"\n" if ensure_
663
- result+="\nend"
667
+ result+=unparse_nl(else_,o)+"else "+else_.unparse( o )+"\n" if else_
668
+ result+=unparse_nl(ensure_,o)+"ensure "+ensure_.unparse( o )+"\n" if ensure_
669
+ result+=";end"
670
+ return result
671
+ end
672
+ end
673
+
674
+ class OneLineParenedNode < ParenedNode
675
+ #hacky way to get unparser to not emit newlines in most cases
676
+ def unparse(o=default_parse_options)
677
+ old_linenum=o[:linenum]
678
+ o[:linenum]=2**128
679
+ result=super(o)
680
+ diff=o[:linenum]-2**128
681
+ o[:linenum]=old_linenum+diff
664
682
  return result
665
683
  end
666
684
  end
@@ -674,7 +692,7 @@ class Macro
674
692
  [
675
693
  -[KW('macro'), KW(beginsendsmatcher).~.*, KW('end'), KW(/^(do|\{)$/).~.la]>>MisparsedNode
676
694
  ]+super+[
677
- -[Op('^@'), Expr, LowerOp]>>FormParameterNode,
695
+ -[Op('^@'), Expr, lower_op()]>>FormParameterNode,
678
696
  -[Op(':@'), (ParenedNode&-{:size=>1})|(VarLikeNode&-{:ident=>"nil"})]>>FormNode,
679
697
  -['macro', CallSiteNode, KW(';'),
680
698
  Expr.-, RescueNode.*, ElseNode.-, EnsureNode.-,
@@ -110,7 +110,7 @@ class Macro
110
110
  #
111
111
  # +o+:: a list of options for unparse
112
112
  #
113
- def unparse o
113
+ def unparse o=default_unparse_options
114
114
  ":("+text.unparse(o)+")"
115
115
  end
116
116
 
@@ -193,7 +193,7 @@ class Macro
193
193
  #
194
194
  # +o+:: a list of options for unparse
195
195
  #
196
- def unparse o
196
+ def unparse o=default_unparse_options
197
197
  "^"+val.unparse(o)
198
198
  end
199
199
 
@@ -205,7 +205,7 @@ class Macro
205
205
  end
206
206
 
207
207
  def inspect
208
- val.unparse({})
208
+ val.unparse
209
209
  end
210
210
  end
211
211
  end
@@ -18,5 +18,5 @@
18
18
 
19
19
 
20
20
  class Macro
21
- VERSION="0.1.3"
21
+ VERSION="0.1.4"
22
22
  end
@@ -0,0 +1,17 @@
1
+ class WeakKeyHash<Hash
2
+ def initialize(&block)
3
+ super
4
+ end
5
+
6
+
7
+ def [](key)
8
+ super key.__id__
9
+ end
10
+
11
+ def []=(key,val)
12
+ ObjectSpace.define_finalizer(key,&method :delete)
13
+ super key.__id__,val
14
+ end
15
+
16
+ #dunno how many more methods will actually work...
17
+ end
@@ -30,10 +30,10 @@ class ExpandTest < Test::Unit::TestCase
30
30
  RedParse::LiteralNode[2]], nil, nil]], nil, nil]
31
31
  ttt.macro_expand(Macro::GLOBALS,{})
32
32
 
33
- assert_equal ttt.unparse({}),'p(1+2)'
33
+ assert_equal ttt.unparse,'p((1+2))'
34
34
 
35
35
  ttt=Macro.parse "p(simple(1,2))"
36
36
  ttt.macro_expand(Macro::GLOBALS,{})
37
- assert_equal ttt.unparse({}),'p(1+2)'
37
+ assert_equal ttt.unparse,'p((1+2))'
38
38
  end
39
39
  end
@@ -37,7 +37,7 @@ class FormTest< Test::Unit::TestCase
37
37
  end
38
38
  next
39
39
  end
40
- define_method "test_case_#{i}" do
40
+ define_method "test_form_around_#{x.gsub(/[^ -~]/){|ch| "\\x"+ch[0].to_s(16)}}" do
41
41
  check x
42
42
  end
43
43
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubymacros
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caleb Clausen
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-03 00:00:00 -07:00
12
+ date: 2009-05-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.8.1
23
+ version: 0.8.2
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: hoe
@@ -47,7 +47,6 @@ files:
47
47
  - Manifest.txt
48
48
  - README.txt
49
49
  - History.txt
50
- - rubymacros.vpj
51
50
  - Rakefile
52
51
  - test/test_form.rb
53
52
  - test/test_expand.rb
@@ -68,8 +67,12 @@ files:
68
67
  - example/linenum.rb
69
68
  - example/linenum_user.rb
70
69
  - example/linenum_wrap.rb
70
+ - example/andand_wrap.rb
71
+ - lib/weakkeyhash.rb
72
+ - test/test_all.rb
73
+ - TODO
71
74
  has_rdoc: true
72
- homepage: http://rubymacros.rubyforge.org/
75
+ homepage: http://github.com/coatl/rubymacros/
73
76
  post_install_message:
74
77
  rdoc_options:
75
78
  - --main
@@ -1,87 +0,0 @@
1
- <!DOCTYPE Project SYSTEM "http://www.slickedit.com/dtd/vse/10.0/vpj.dtd">
2
- <Project
3
- Version="10.0"
4
- VendorName="SlickEdit"
5
- WorkingDir=".">
6
- <Config
7
- Name="Release"
8
- OutputFile=""
9
- CompilerConfigName="Latest Version">
10
- <Menu>
11
- <Target
12
- Name="Compile"
13
- MenuCaption="&amp;Compile"
14
- CaptureOutputWith="ProcessBuffer"
15
- SaveOption="SaveCurrent"
16
- RunFromDir="%rw">
17
- <Exec/>
18
- </Target>
19
- <Target
20
- Name="Build"
21
- MenuCaption="&amp;Build"
22
- CaptureOutputWith="ProcessBuffer"
23
- SaveOption="SaveWorkspaceFiles"
24
- RunFromDir="%rw">
25
- <Exec/>
26
- </Target>
27
- <Target
28
- Name="Rebuild"
29
- MenuCaption="&amp;Rebuild"
30
- CaptureOutputWith="ProcessBuffer"
31
- SaveOption="SaveWorkspaceFiles"
32
- RunFromDir="%rw">
33
- <Exec/>
34
- </Target>
35
- <Target
36
- Name="Debug"
37
- MenuCaption="&amp;Debug"
38
- SaveOption="SaveNone"
39
- RunFromDir="%rw">
40
- <Exec/>
41
- </Target>
42
- <Target
43
- Name="Execute"
44
- MenuCaption="E&amp;xecute"
45
- SaveOption="SaveNone"
46
- RunFromDir="%rw">
47
- <Exec CmdLine='".exe"'/>
48
- </Target>
49
- </Menu>
50
- </Config>
51
- <CustomFolders>
52
- <Folder
53
- Name="Source Files"
54
- Filters="*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl"/>
55
- <Folder
56
- Name="Header Files"
57
- Filters="*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if"/>
58
- <Folder
59
- Name="Resource Files"
60
- Filters="*.ico;*.cur;*.dlg"/>
61
- <Folder
62
- Name="Bitmaps"
63
- Filters="*.bmp"/>
64
- <Folder
65
- Name="Other Files"
66
- Filters="">
67
- </Folder>
68
- </CustomFolders>
69
- <Files AutoFolders="DirectoryView">
70
- <Folder Name="example">
71
- <F N="example/assert.rb"/>
72
- <F N="example/assert_wrap.rb"/>
73
- <F N="example/simple.rb"/>
74
- <F N="example/simple_wrap.rb"/>
75
- </Folder>
76
- <Folder Name="lib">
77
- <Folder Name="macro">
78
- <F N="lib/macro/form.rb"/>
79
- </Folder>
80
- <F N="lib/macro.rb"/>
81
- <F N="lib/weakkeyhash.rb"/>
82
- </Folder>
83
- <Folder Name="test">
84
- <F N="test/test_form.rb"/>
85
- </Folder>
86
- </Files>
87
- </Project>