引数付きマクロ処理(一部修正)2017年01月26日 21:27

マクロの定義に、引数が使えるようになると、利便性が非常に向上する。簡単な例を 示す。まずは、マクロの定義は、以下のようになる。マクロgetc,putcの定義の中、$1が マクロの引数にである。引数は、$1から$9までである。

          define(STDIN,5)
          define(STDOUT,6)
          define(getc,getch(STDIN,$1))
          define(putc,putch(STDOUT,$1))

プログラム中では、以下のように、記述する。

          c = getc(c)
          call putc(c)

これが展開されると、以下のようになる。

          c = getch(5,c)
          call putch(6,c)

もう少し長いマクロの例を以下に示す。

          define(BLANK,32)
          define(TAB,9)
          define(skipbl,while($1($2) == BLANK | $1($2) == TAB)
               $2 = $2 + 1)

プログラム中では、

          skipbl(s,i)

展開されると、

          while(s(i) == 32 | s(i) == 9)
              i = i + 1

読み込み中にマクロに出会ったら、引数も含めてマクロ評価用スタックに積む。 引数の中にマクロ呼び出しがあったら、新しいマクロ評価用スタック領域を取り、 スタックに積む。そして、マクロを完全に評価して、入力に送り返す。そして、元の マクロの評価を続ける。

マクロ評価用スタックevalstは配列で表現され、マクロの名前、定義型、 引数が入る。一方、配列argstkは、evalstに格納された文字列の場所の 位置を示す。いくつものモジュールで共通の用いられるevalstは以下の通り。

RATFOR版は、

# cmacro.ri
      common /cmacro/cp,ep,evalst(EVALSIZE)
      integer cp       # current call stack pointer
      integer ep       # next free position in evalst
      character evalst # evaluation stack

WATCOM fortran 77版は、

! cmacro.fi
      common /cmacro/cp,ep,evalst(EVALSIZE)
      integer cp       ! current call stack pointer
      integer ep       ! next free position in evalst
      integer*1 evalst ! evaluation stack

このマクロでは、マクロや組み込み操作は出現したとき、 その場で全て展開することになっているので、それではまずいことがある。 たとえば、defをdefineの同義語として定義したいとき、

      define(def,define($1,$2))

とすれば良さそうだが、うまくいかない。まず、マクロ名"def"が、評価用スタックに積まれる。 次に、置き換え文字列"define($1,$2)"が評価されてしまい、"def"に対応する置き換え文字列が 空となってしまう。 これでは、目的を達成できないので、"["と"]"でくくられた範囲は、評価を遅らせる仕組みを 付け加える。

      define(def,[define($1,$2)])
      def(ABC,DEF)

とすると

      ABC

は、変換されて、

      DEF

となる。実は、引数なしのマクロプログラムのソースは、defineを通せない。 プログラム中のマクロ定義ではない"define"文字列がマクロの定義と 見間違えられてしまうのである。

引数なしのマクロには、"()"がつかない、これを特別扱いしないように、 "()"がついていないマクロに出会ったら、"()"を入力に送り返し、あたかも"()"が つぃているかのように振る舞わせる。

以上を踏まえた、引数付きマクロのRATFOR版は、以下の通り。

# macro.r4 -- expand macros with arguments
      program macro
      character gettok
      integer*1 defn(MAXDEF),t,token(MAXTOK)
      integer lookup,push
      integer ap,argstk(ARGSIZE),callst(CALLSIZE),nlb,plev(CALLSIZE)

      string balp "()"
      string defnam "define"
      character deftyp(2)
      data deftyp(1)/DEFTYPE/,deftyp(2)/EOS/

      include cmacro.fi

      call initfile
      call inittbl
      call instal(defnam,deftyp)
      cp = 0
      ap = 1
      ep = 1
      for (t = gettok(token,MAXTOK); t !=  EOF; t = gettok(token,MAXTOK)) {
          if (t == ALPHA) {
              if (lookup(token,defn) == NO)
                  call puttok(token)
              else {                    # defined; put it in eval stack
                  cp = cp + 1
                  if (cp > CALLSIZE) then
                      call error('call stack overflow.')
                  callst(cp) = ap
                  ap = push(ep,argstk,ap)
                  call puttok(defn)     # stack definition
                  call putchr(EOS)
                  ap = push(ep,argstk,ap)
                  call puttok(token)    # stack name
                  call putchr(EOS)
                  ap = push(ep,argstk,ap)
                  t = gettok(token,MAXTOK) # peek at next
                  call pbstr(token)
                  if (t != LPAREN)      # add ( ) if not present
                      call pbstr(balp)
                  plev(cp) = 0
                  }
              }
          else if (t == LBRACK) {       # strip one level of [ ]
              nlb = 1
              repeat {
                  t = gettok(token,MAXTOK)
                  if (t == LBRACK)
                      nlb = nlb + 1
                  else if (t == RBRACK) {
                      nlb = nlb - 1
                      if (nlb == 0)
                          break
                      }
                  else if (t == EOF)
                      call error('EOF in string.')
                  call puttok(token)
                  }
          else if (cp == 0)             # not in a macro at all
              call puttok(token)
          else if (t == LPAREN)
              if (plev(cp) > 0)
                  call puttok(token)
              plev(cp) = plev(cp) + 1
          else if (t == RPAREN) {
              plev(cp) = plev(cp) - 1
              if (plev(cp) .gt. 0) then
                  call puttok(token)
              else {                    # end of argument list
                  call putchr(EOS)
                  call eval(argstk,callst(cp),ap-1)
                  ap = callst(cp)       # pop eval stack
                  ep = argstk(ap)
                  cp = cp - 1
                  }
          else if ((t == COMMA) $ (plev(cp) == 1)) {
              call putchr(EOS)
              ap = push(ep,argstk,ap)
              }
          else
              call puttok(token)
          }
      if (cp != 0)
          call error('unexpected EOF.')
      stop
      end

WATCOM fortran 77版は、

! macro.f -- expand macros with arguments
      include ratfor.def
      program macro
      integer*1 gettok
      integer*1 defn(MAXDEF),t,token(MAXTOK)
      integer lookup,push
      integer ap,argstk(ARGSIZE),callst(CALLSIZE),nlb,plev(CALLSIZE)

      integer*1 balp(3)
      data balp(1)/LPAREN/
      data balp(2)/RPAREN/
      data balp(3)/EOS/

      integer*1 defnam(7)
      data defnam(1)/LETd/
      data defnam(2)/LETe/
      data defnam(3)/LETf/
      data defnam(4)/LETi/
      data defnam(5)/LETn/
      data defnam(6)/LETe/
      data defnam(7)/EOS/

      integer*1 deftyp(2)
      data deftyp(1)/DEFTYPE/
      data deftyp(2)/EOS/
      include cmacro.fi

      call initfile
      call inittbl
      call instal(defnam,deftyp)
      cp = 0      ! current call stack pointer
      ap = 1      ! next free position in argstk
      ep = 1      ! next free position in evalst
      t = gettok(token,MAXTOK) 
      while (t .ne. EOF) do
          if (t .eq. ALPHA) then
              if (lookup(token,defn) .eq. NO) then
                  call puttok(token)
              else                          ! defined; put it in eval stack
                  cp = cp + 1
                  if (cp .gt. CALLSIZE) then
                      call error('call stack overflow.')
                  end if
                  callst(cp) = ap
                  ap = push(ep,argstk,ap)
                  call puttok(defn)         ! stack definition
                  call putchr(EOS)
                  ap = push(ep,argstk,ap)
                  call puttok(token)        ! stack name
                  call putchr(EOS)
                  ap = push(ep,argstk,ap)
                  t = gettok(token,MAXTOK)  ! peek at next
                  call pbstr(token)
                  if (t .ne. LPAREN) then   ! add ( ) if not present
                      call pbstr(balp)
                  end if
                  plev(cp) = 0
              end if
          else if (t .eq. LBRACK) then      ! strip one level of [ ]
              nlb = 1
              loop
                  t = gettok(token,MAXTOK)
                  if (t .eq. LBRACK) then
                      nlb = nlb + 1
                  else if (t .eq. RBRACK) then
                      nlb = nlb - 1
                      if (nlb .eq. 0) then
                          exit
                      end if
                  else if (t .eq. EOF) then
                      call error('EOF in string.')
                  end if
                  call puttok(token)
              end loop
          else if (cp .eq. 0) then          ! not in a macro at all
              call puttok(token)
          else if (t .eq. LPAREN) then
              if (plev(cp) .gt. 0) then
                  call puttok(token)
              end if
              plev(cp) = plev(cp) + 1
          else if (t .eq. RPAREN) then
              plev(cp) = plev(cp) - 1
              if (plev(cp) .gt. 0) then
                  call puttok(token)
              else                         ! end of argument list
                  call putchr(EOS)
                  call eval(argstk,callst(cp),ap-1)
                  ap = callst(cp)          ! pop eval stack
                  ep = argstk(ap)
                  cp = cp - 1
              end if
          else if ((t .eq. COMMA) .and. (plev(cp) .eq. 1)) then
              call putchr(EOS)
              ap = push(ep,argstk,ap)
          else
              call puttok(token)
          end if
          t = gettok(token,MAXTOK)
      end while

      if (cp .ne. 0) then
          call error('unexpected EOF.')
      end if

      stop
      end

下請けルーチンputtok()のRATFOR版は、以下の通り。

# puttok.r4 -- put a token either on output or into evaluation stack
      subroutine puttok(str)
      character str(MAXTOK)
      integer i

      for (i = 1; str(i) != EOS; i = i + 1)
          call putchr(str(i))
      return
      end

WATCOM fortran 77版は、

! puttok.f -- put a token either on output or into evaluation stack
      include ratfor.def
      subroutine puttok(str)
      integer*1 str(MAXTOK)
      integer i

      i = 1
      while (str(i) .ne. EOS) do
          call putchr(str(i))
          i = i + 1
      end while
      return
      end

下請けルーチンputchr()のRATFOR版は、以下の通り。

# putchr -- put single char on output or into eveluation stack
      subroutine putchr(c)
      character c
      include cmacror.ri

      if (cp == 0)
          call putc(c)
      else {
          if (ep > EVALSIZE)
              call error('eveluation stack overflow.')
          evalst(ep) = c
          ep = ep + 1
          }
      return
      end

WATCOM fortran 77版は、

! putchr -- put single char on output or into eveluation stack
      include ratfor.def
      subroutine putchr(c)
      integer*1 c
      include cmacro.fi

      if (cp .eq. 0) then
          call putc(c)
      else
          if (ep .gt. EVALSIZE) then
              call error('eveluation stack overflow.')
          end if
          evalst(ep) = c
          ep = ep + 1
      end if
      return
      end

下請けルーチンeval()のRATFOR版は、以下の通り。

# eval.r4 - expand args i through j: evaluate builtin or push back defn
      subroutine eval(argstk,i,j)
      integer i,j,argstk(ARGSIZE)
      integer iindex,length
      integer argno,k,m,n,t,td
      include cmacro.ri
      string digits "0123456789"

      t = argstk(i)
      td = evalst(t)
      if (td == DEFTYPE)
          call dodef(argstk,i,j)
      else {
          for (k = t + length(evalst(t)) - 1; k > t); k = k - 1)
              if (evalst(k-1) != ARGFLAG)
                  call putbak(evalst(k))
              else {
                  argno = iindex(digits,evalst(k)) - 1
                  if (argno >= 0) {
                      n = i + argno + 1
                      m = argstk(n)
                      call pbstr(evalst(m))
                      }
                  k = k - 1     # skip over $
                  }
          if (k == t)           # do last character
              call putbak(evalst(k))
          }
      return
      end

WATCOM fortran 77版は、

! eval.f - expand args i through j: evaluate builtin or push back defn
      include ratfor.def
      subroutine eval(argstk,i,j)
      integer i,j,argstk(ARGSIZE)
      integer iindex,length
      integer argno,k,m,n,t,td
      include cmacro.fi

      integer*1 digits(11)
      data digits(1)/LET0/
      data digits(2)/LET1/
      data digits(3)/LET2/
      data digits(4)/LET3/
      data digits(5)/LET4/
      data digits(6)/LET5/
      data digits(7)/LET6/
      data digits(8)/LET7/
      data digits(9)/LET8/
      data digits(10)/LET9/
      data digits(11)/EOS/

      t = argstk(i)
      td = evalst(t)
      if (td .eq. DEFTYPE) then
          call dodef(argstk,i,j)
      else
          k = t + length(evalst(t)) - 1
          while (k .gt. t) do
              if (evalst(k-1) .ne. ARGFLAG) then
                  call putbak(evalst(k))
              else
                  argno = iindex(digits,evalst(k)) - 1
                  if (argno .ge. 0) then
                      n = i + argno + 1
                      m = argstk(n)
                      call pbstr(evalst(m))
                  end if
                  k = k - 1       ! skip over $
              end if
              k = k - 1
          end while
          if (k .eq. t) then
              call putbak(evalst(k))
          end if
      end if
      return
      end

下請けルーチンdodef()のRATFOR版は、以下の通り。

# dodef.rf -- install definition in table
      subroutine dodef(argstk,i,j)
      integer i,j,argstk(ARGSIZE)
      integer a2,a3
      include cmacro.ri

      if (j-i .gt. 2) {
          a2 = argstk(i+2)
          a3 = argstk(i+3)
          call instal(evalst(a2),evalst(a3))  # subarrays
          }
      return
      end

WATCOM fortran 77版は、

! dodef.f -- install definition in table
      include ratfor.def
      subroutine dodef(argstk,i,j)
      integer i,j,argstk(ARGSIZE)
      integer a2,a3
      include cmacro.fi

      if (j-i .gt. 2) then
          a2 = argstk(i+2)
          a3 = argstk(i+3)
          call instal(evalst(a2),evalst(a3))  ! subarrays
      end if
      return
      end

コメント

_ gordon ― 2017年02月19日 16:55

_ JimmiXzSw ― 2017年02月19日 22:19

_ tinder dating site ― 2017年02月25日 23:54

Thanks very interesting blog!

_ tinder dating site ― 2017年02月26日 05:20

Wow! This blog looks just like my old one! It's
on a completely different subject but it has pretty much the same page layout and
design. Great choice of colors!

_ tinder dating site ― 2017年03月01日 02:54

I have been surfing online more than 2 hours today, yet I
never found any interesting article like yours.
It's pretty worth enough for me. In my view, if
all webmasters and bloggers made good content as you did,
the net will be much more useful than ever before.

_ tinder dating site ― 2017年03月01日 23:32

Howdy! I know this is kinda off topic but I was wondering which
blog platform are you using for this site? I'm getting tired of Wordpress because I've
had problems with hackers and I'm looking at alternatives for another
platform. I would be awesome if you could point me in the
direction of a good platform.

_ minecraft ― 2017年03月02日 21:46

Very shortly this site will be famous among all blogging
and site-building users, due to it's fastidious articles or reviews

_ tinder dating site ― 2017年03月05日 01:14

Magnificent items from you, man. I have have in mind your stuff prior to and you are just too wonderful.
I actually like what you've obtained right here, really
like what you are saying and the way in which by which you assert it.

You are making it enjoyable and you still take care of to
stay it smart. I can not wait to read much more from you.
That is actually a wonderful web site.

_ tinder ― 2017年03月05日 10:32

It is really a nice and helpful piece of info. I
am glad that you simply shared this helpful information with us.
Please keep us informed like this. Thank you for sharing.

_ Dating Sites Santa Clarita California ― 2017年03月08日 07:48

Thanks for your marvelous posting! I seriously enjoyed reading it,
you could be a great author.I will ensure that I bookmark your blog and may come back later in life.
I want to encourage you to definitely continue your great
job, have a nice morning!

_ manicure ― 2017年03月09日 17:59

Excellent post. I was checking continuously
this blog and I'm impressed! Very useful info specifically the last part :
) I care for such info a lot. I was seeking this certain information for a very long time.
Thank you and good luck.

_ sandcity.mrdrain.com ― 2017年03月09日 23:25

I every time used to study piece of writing in news papers but now as
I am a user of net thus from now I am using net for articles or reviews, thanks to
web.

_ tinyurl.com ― 2017年03月10日 21:35

First of all I would like to say fantastic blog!
I had a quick question which I'd like to ask if you do not mind.
I was curious to find out how you center yourself
and clear your thoughts prior to writing. I've had trouble clearing my mind in getting
my thoughts out. I do enjoy writing however it just seems like
the first 10 to 15 minutes tend to be lost simply just trying to figure out how to begin. Any ideas or hints?
Appreciate it!

_ http://tinyurl.com/ ― 2017年03月10日 22:25

Remarkable! Its really amazing piece of writing, I have got
much clear idea on the topic of from this piece of writing.

_ tinyurl.com ― 2017年03月11日 15:34

Howdy! This is kind of off topic but I need some advice from
an established blog. Is it hard to set up your own blog?
I'm not very techincal but I can figure things out
pretty quick. I'm thinking about creating my own but I'm not sure
where to start. Do you have any ideas or suggestions?
Thanks

_ http://tinyurl.com/zdqd423 ― 2017年03月11日 22:39

I loved as much as you will receive carried out right here.
The sketch is tasteful, your authored subject matter stylish.

nonetheless, you command get got an nervousness over that you
wish be delivering the following. unwell unquestionably
come further formerly again since exactly the same nearly a lot often inside
case you shield this hike.

_ http://j.mp/2m9zSBJ ― 2017年03月12日 03:48

Someone necessarily help to make seriously posts I would state.
This is the first time I frequented your web page and up to now?

I amazed with the analysis you made to create this particular put up incredible.
Fantastic activity!

_ tinder dating site ― 2017年03月13日 15:54

I blog often and I really appreciate your content.
The article has really peaked my interest. I will book mark your site
and keep checking for new information about once per week.
I subscribed to your RSS feed as well.

_ tinder dating site ― 2017年03月19日 04:52

Howdy, i read your blog occasionally and i own a similar one and
i was just wondering if you get a lot of spam
responses? If so how do you protect against it, any plugin or anything you can advise?

I get so much lately it's driving me mad so any
assistance is very much appreciated.

_ tinder dating site ― 2017年03月19日 14:36

Greetings! This is my first comment here so I just
wanted to give a quick shout out and say I really enjoy reading your
articles. Can you suggest any other blogs/websites/forums that deal with the same
subjects? Thanks for your time!

_ tinder dating site ― 2017年03月20日 17:15

Saved as a favorite, I like your site!

_ free dating sites no fees ― 2017年03月21日 22:39

I'm really impressed with your writing skills and also with the structure on your blog.
Is this a paid theme or did you customize it your self?

Either way keep up the nice quality writing, it is uncommon to see
a nice blog like this one these days..

_ free dating sites no fees ― 2017年03月22日 02:27

This is a topic which is close to my heart... Best wishes!
Where are your contact details though?

_ top ten free dating sites 2017 ― 2017年03月22日 04:27

I really like what you guys are up too. Such clever
work and exposure! Keep up the fantastic works guys I've
added you guys to blogroll.

_ five best free dating sites ― 2017年03月23日 06:31

Very energetic blog, I liked that a lot. Will there be a part 2?

_ free dating sites no fees ― 2017年03月23日 07:41

Excellent post! We are linking to this great
content on our site. Keep up the great writing.

_ free dating sites no fees ― 2017年03月23日 10:14

I think this is among the most important info for me.
And i am glad reading your article. But wanna remark on some general things,
The site style is perfect, the articles is really excellent :
D. Good job, cheers

_ minecraft games ― 2017年03月26日 01:59

Hello, i believe that i noticed you visited
my weblog thus i came to go back the favor?.I'm trying to find issues to
enhance my website!I suppose its good enough to use some of
your concepts!!

_ minecraft demo ― 2017年03月26日 15:06

Hello there, just became aware of your blog through Google, and found that it is really informative.
I am going to watch out for brussels. I will be grateful if you continue this in future.
Many people will be benefited from your writing. Cheers!

_ manicure ― 2017年04月03日 11:34

Have you ever thought about publishing an e-book or guest authoring on other websites?
I have a blog based upon on the same ideas you discuss and would love to have you share some stories/information. I
know my audience would value your work. If you're even remotely interested, feel free to shoot me an e-mail.

_ BHW ― 2017年04月12日 18:55

These are truly wonderful ideas in about blogging. You have touched some good factors
here. Any way keep up wrinting.

_ BHW ― 2017年04月16日 15:16

It's an remarkable paragraph in support of all the internet people; they
will take advantage from it I am sure.

_ www.krogerfeedback.com ― 2017年04月29日 11:10

I was suggested this blog by my cousin. I'm not sure whether this post is written by him as no one
else know such detailed about my trouble. You are amazing!
Thanks!

_ www.krogerfeedback.com ― 2017年04月30日 23:11

I love what you guys are up too. This kind of clever work and exposure!

Keep up the wonderful works guys I've included you guys to blogroll.

_ www.krogerfeedback.com ― 2017年05月01日 03:20

Heya i am for the primary time here. I found this board and I find It really helpful & it helped
me out a lot. I hope to give something back
and aid others such as you helped me.

_ manicure ― 2017年05月03日 11:50

Hi, Neat post. There is a problem along with your web site in internet
explorer, would check this? IE nonetheless
is the market chief and a large section of other people will pass
over your excellent writing due to this problem.

_ manicure ― 2017年05月04日 01:35

Howdy! I could have sworn I've visited this site before but after looking
at a few of the articles I realized it's new to me. Nonetheless,
I'm certainly delighted I found it and I'll be book-marking it and
checking back regularly!

_ Minecraft ― 2017年05月19日 20:45

Good day! I know this is somewhat off topic but I was wondering if you knew where
I could find a captcha plugin for my comment form?
I'm using the same blog platform as yours and I'm having trouble finding one?

Thanks a lot!

_ Minecraft ― 2017年05月20日 04:40

I blog frequently and I really appreciate your content.
Your article has truly peaked my interest. I will book mark your site and keep
checking for new details about once a week. I opted in for your RSS feed as well.

_ Minecraft Maps ― 2017年05月22日 21:34

Greate pieces. Keep writing such kind of info on your site.

Im really impressed by your blog.
Hey there, You have performed an excellent job. I will certainly digg it and in my opinion suggest to
my friends. I am sure they'll be benefited from this web site.

_ instacart coupon 2017 ― 2017年08月20日 15:11

Thank you for the good writeup. It in fact was a
amusement account it. Look advanced to more added agreeable from you!
By the way, how could we communicate?

_ http://tinyurl.com ― 2017年08月21日 16:35

Usually I do not read article on blogs, however I would like to say that this write-up very compelled me to try and do so!
Your writing taste has been amazed me. Thank you, quite nice post.

_ instacart coupon 2017 ― 2017年08月21日 23:52

Hello, i think that i saw you visited my weblog so
i came to “return the favor”.I'm attempting to find things to improve my website!I suppose its ok to use a few of your ideas!!

_ http://tinyurl.com ― 2017年08月22日 04:31

Ahaa, its good conversation regarding this piece of writing
here at this website, I have read all that, so now me also commenting at
this place.

_ http://tinyurl.com/ ― 2017年08月22日 16:49

Hey there fantastic website! Does running a blog such as this require
a massive amount work? I've absolutely no understanding of programming but I was
hoping to start my own blog in the near
future. Anyhow, should you have any ideas or techniques for new blog owners please share.
I understand this is off subject nevertheless I simply wanted to ask.
Thank you!

_ tinyurl.com ― 2017年08月24日 21:26

First of all I would like to say wonderful blog!
I had a quick question in which I'd like to ask
if you do not mind. I was curious to find out how you center yourself and clear your head before writing.

I have had a tough time clearing my thoughts in getting
my ideas out. I do take pleasure in writing but it just seems
like the first 10 to 15 minutes tend to be lost simply just trying to figure out how to begin. Any ideas or tips?
Thanks!

_ http://tinyurl.com/ ― 2017年08月24日 23:38

I'm gone to inform my little brother, that he should also pay a
visit this website on regular basis to obtain updated from
newest news update.

_ tinyurl.com ― 2017年08月25日 07:43

Hi Dear, are you in fact visiting this website on a regular basis, if
so afterward you will without doubt take pleasant experience.

_ http://tinyurl.com/y78oxdfc ― 2017年08月25日 15:42

Have you ever thought about writing an e-book or guest
authoring on other blogs? I have a blog based upon on the same
ideas you discuss and would really like to have you share some stories/information. I know my readers would
value your work. If you're even remotely interested, feel free to shoot me an e-mail.

_ tinyurl.com ― 2017年08月25日 16:03

Excellent article. I will be going through
a few of these issues as well..

※コメントの受付件数を超えているため、この記事にコメントすることができません。

トラックバック

このエントリのトラックバックURL: http://kida.asablo.jp/blog/2017/01/26/8334952/tb