rubymacros 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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>