OSDN Git Service

Initial Update. master
authornight <night@ubantu.(none)>
Tue, 25 Nov 2014 10:41:48 +0000 (19:41 +0900)
committernight <night@ubantu.(none)>
Tue, 25 Nov 2014 10:41:48 +0000 (19:41 +0900)
12 files changed:
ChangeLog [new file with mode: 0644]
VERSION [new file with mode: 0644]
compiler/ChangeLog [new file with mode: 0644]
compiler/Makefile [new file with mode: 0644]
compiler/bcpl.h [new file with mode: 0644]
compiler/debug.c [new file with mode: 0644]
compiler/lexical.l [new file with mode: 0644]
compiler/main.c [new file with mode: 0644]
compiler/makecode.c [new file with mode: 0644]
compiler/misc.c [new file with mode: 0644]
compiler/parser.y [new file with mode: 0644]
example/foo.bcp [new file with mode: 0644]

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..51a1159
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,7 @@
+Sat Sep  4 15:51:33 1999  Ryuichi Naitoh  <night@ibmpc0.bfree.rim.or.jp>
+
+       * VERSION: 
+       bcplc ¤ò CVS ¤Î´ÉÍý¤«¤éÂоݳ°¤Ë¤·¤¿¡£
+       ¥ª¥Ú¥ì¡¼¥¿ & ¤Î¥È¡¼¥¯¥ó¤ò TK_AND ¤«¤é TK_ANDOP ¤ËÊѹ¹¤·¤¿¡£
+       ¤Þ¤¿¡¢BE ¤È¤¤¤¦Í½Ìó¸ìÍѤΥȡ¼¥¯¥ó¤ò TK_AND ¤È¤·¤ÆÄêµÁ¤·¤¿¡£
+       procedure ¤Î¹½Ê¸ÄêµÁ¤Ë AND ¤¬Íè¤ë¾ì¹ç¤òÄɲä·¤¿¡£
diff --git a/VERSION b/VERSION
new file mode 100644 (file)
index 0000000..05b19b1
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.0.4
\ No newline at end of file
diff --git a/compiler/ChangeLog b/compiler/ChangeLog
new file mode 100644 (file)
index 0000000..a4f9c29
--- /dev/null
@@ -0,0 +1,14 @@
+Sun Sep  5 08:48:52 1999  Ryuichi Naitoh  <night@ibmpc0.bfree.rim.or.jp>
+
+       * bcpl.h debug.c lexical.l misc.c parser.y
+       BCPL ¤ÎÆÃħ¤Î¤Ò¤È¤Ä¤Ç¤¢¤ë¡¢¥¿¥°ÉÕ¤­¤Î¶è´Ö¤«¤Ã¤³¤ò»È¤Ã¤¿¤È¤­¤Ë¡¢¶è´Ö¤«¤Ã
+       ¤³¤Î¾Êά¤Ç¤­¤ëµ¡Ç½¤ò¥µ¥Ý¡¼¥È¤·¤¿¡£
+
+Sat Sep  4 15:50:48 1999  Ryuichi Naitoh  <night@ibmpc0.bfree.rim.or.jp>
+
+       * .cvsignore: bcplc ¤ò CVS ¤Î´ÉÍý¤«¤éÂоݳ°¤Ë¤·¤¿¡£
+
+       * parser.y lexical.l
+         ¥ª¥Ú¥ì¡¼¥¿ & ¤Î¥È¡¼¥¯¥ó¤ò TK_AND ¤«¤é TK_ANDOP ¤ËÊѹ¹¤·¤¿¡£
+         ¤Þ¤¿¡¢BE ¤È¤¤¤¦Í½Ìó¸ìÍѤΥȡ¼¥¯¥ó¤ò TK_AND ¤È¤·¤ÆÄêµÁ¤·¤¿¡£
+         procedure ¤Î¹½Ê¸ÄêµÁ¤Ë AND ¤¬Íè¤ë¾ì¹ç¤òÄɲä·¤¿¡£
diff --git a/compiler/Makefile b/compiler/Makefile
new file mode 100644 (file)
index 0000000..ea50c02
--- /dev/null
@@ -0,0 +1,40 @@
+#
+#
+#
+
+
+CFLAGS=
+
+all: bcplc
+
+bcplc: main.o lexical.o parser.tab.o makecode.o misc.o debug.o
+       cc -o bcplc main.o lexical.o parser.tab.o makecode.o misc.o debug.o -lfl
+
+
+main.o: main.c bcpl.h
+       cc $(CFLAGS) -c main.c
+
+misc.o: misc.c parser.tab.c bcpl.h
+       cc $(CFLAGS) -c misc.c
+
+debug.o: debug.c parser.tab.c bcpl.h
+       cc $(CFLAGS) -c debug.c
+
+lexical.o: lexical.c parser.tab.c bcpl.h
+       cc $(CFLAGS) -c lexical.c
+
+
+lexical.c: lexical.l bcpl.h
+       flex -olexical.c lexical.l
+
+parser.tab.o: parser.tab.c bcpl.h
+       cc $(CFLAGS) -c parser.tab.c
+
+parser.tab.c: parser.y bcpl.h
+       bison -v -t -d parser.y
+
+
+
+clean:
+       rm -f bcplc *.o parser.tab.c parser.tab.h *~ core lexical.c parser.output
+
diff --git a/compiler/bcpl.h b/compiler/bcpl.h
new file mode 100644 (file)
index 0000000..fe1d026
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+
+#define MAX_STRING_LENGTH      255
+#define MAX_TAG                        10
+
+struct symbol
+{
+  int          type;
+  struct symbol        *hash;
+  int          length;
+  char         *value;
+};
+
+
+struct string
+{
+  int          type;
+  int          length;
+  char         *value;
+};
+
+
+struct character
+{
+  int          type;
+  int          value;
+};
+
+
+struct number
+{
+  int          type;
+  int          value;
+};
+
+
+struct node
+{
+  int          type;
+  void         *head;
+  void         *body;
+  void         *next;
+};
+
+
+#define OP_MANIFEST            1
+#define OP_CONST               2
+#define OP_DECLARE             3
+#define OP_GLOBAL              4
+#define OP_EXPR                        5
+#define OP_PLUSOP              6
+#define OP_SUBOP               7
+#define OP_FUNCTION            8
+#define OP_ARGS                        9
+#define OP_STATEMENT           10
+#define OP_PROCEDURE           11
+#define OP_CALL                        12
+#define OP_VALOF               13
+#define OP_RETURN              14
+#define OP_VARIABLE            15
+#define OP_CONST_LIST          16
+#define OP_INITIALVAR          17
+#define OP_IF                  18
+#define OP_WHILE               19
+#define OP_SET                 20      /* ÂåÆþ */
+#define OP_STATIC              21
+#define OP_MULTOP              22
+#define OP_DIVOP               23
+#define OP_LT                  24
+#define OP_GT                  25
+#define OP_OR                  26
+#define OP_AND                 27
+#define OP_EQUAL               28
+#define OP_VECIS               29      /* ! */
+#define OP_SWITCHON            30
+#define OP_CASE                        31
+#define OP_GE                  32
+#define OP_LE                  33
+#define OP_REPEATUNTIL         34
+#define OP_CASECONT            35
+#define OP_GET                 36
+#define OP_BLOCK               37
+
+
+extern struct symbol   *make_symbol ();
+extern struct string   *make_string ();
+extern struct node     *make_node ();
+extern struct number   *make_number ();
+
+extern void            debug_print ();
+
+extern int             nlcount;
diff --git a/compiler/debug.c b/compiler/debug.c
new file mode 100644 (file)
index 0000000..a64f4cb
--- /dev/null
@@ -0,0 +1,581 @@
+/*
+ *
+ *
+ */
+
+
+#include "bcpl.h"
+#include "parser.tab.h"
+
+
+extern void    print_node ();
+static void    print_symbol ();
+static void    print_string ();
+static void    print_number ();
+static void    print_const ();
+static void    print_declare ();
+static void    print_func ();
+static void    print_proc ();
+static void    print_call ();
+static void    print_expr ();
+static void    print_args ();
+static void    print_arglist ();
+static void    print_statement ();
+static void    print_return ();
+static void    print_variable ();
+static void    print_initialized_variable ();
+static void    print_initial_list ();
+static void    print_assign (struct node *nodep, int indent);
+static void    print_if ();
+static void    print_while ();
+static void    print_switchon (struct node *nodep, int indent);
+static void    print_case (struct node *nodep, int indent);
+static void    print_repeatuntil (struct node *nodep, int indent);
+static void    print_get (struct node *nodep, int indent);
+static void    print_block (struct node *nodep, int indent);
+
+static struct debug_entry      *get_entry ();
+
+
+struct debug_entry
+{
+  int  type;
+  char *nicname;
+  void (*f)();
+};
+
+
+struct debug_entry debug_table[] =
+{
+  { OP_DECLARE,                "declare",      print_declare   },
+  { OP_MANIFEST,       "manifest",     print_node      },
+  { OP_CONST,          "const",        print_const     },
+  { OP_GLOBAL,         "global",       print_node      },
+  { OP_STATIC,         "static",       print_node      },
+  { OP_FUNCTION,       "func",         print_func      },
+  { OP_PROCEDURE,      "proc",         print_proc      },
+  { OP_ARGS,           "args",         print_arglist   },
+  { OP_PLUSOP,         "+",            print_expr      },
+  { OP_SUBOP,          "-",            print_expr      },
+  { OP_MULTOP,         "*",            print_expr      },
+  { OP_DIVOP,          "/",            print_expr      },
+  { OP_GT,             "<",            print_expr      },
+  { OP_LT,             ">",            print_expr      },
+  { OP_GE,             "<=",           print_expr      },
+  { OP_LE,             ">=",           print_expr      },
+  { OP_AND,            "&",            print_expr      },
+  { OP_OR,             "|",            print_expr      },
+  { OP_EQUAL,          "=",            print_expr      },
+  { OP_VECIS,          "!",            print_expr      },
+
+  { OP_STATEMENT,      "-  ",          print_statement },
+  { OP_CALL,           "Call",         print_call      },
+  { OP_RETURN,         "return",       print_return    },
+  { OP_VALOF,          "valof",        print_node      },
+  { OP_VARIABLE,       "var",          print_variable  },
+  { OP_INITIALVAR,     "initvar",      print_initialized_variable },
+  { OP_SET,            "assign",       print_assign },
+  { OP_IF,             "if",           print_if },
+  { OP_WHILE,          "whlie",        print_while },
+  { OP_SWITCHON,       "switchon",     print_switchon },
+  { OP_CASE,           "case",         print_case },
+  { OP_CASECONT,       "case",         print_case },
+  { OP_REPEATUNTIL,    "repeatuntil",  print_repeatuntil },
+  { OP_GET,            "GET",          print_get },
+  { OP_BLOCK,          "BLOCK",        print_block },
+
+  { TK_SYMBOL,         "symbol",       print_symbol    },
+  { TK_STRING,         "string",       print_string    },
+  { TK_NUMBER,         "number",       print_number    },
+  { 0,                 NULL,           NULL            },
+};
+
+
+static struct debug_entry *
+get_entry (nodep)
+     struct node *nodep;
+{
+  int  i;
+
+  if (nodep == NULL)
+    return (NULL);
+
+  for (i = 0; debug_table[i].type != 0; i++)
+    {
+      if (nodep->type == debug_table[i].type)
+       {
+         return (&debug_table[i]);
+       }
+    }
+  return (NULL);
+}
+
+
+static
+print_space (int n)
+{
+  int  i;
+
+  for (i = 0; i < n; i++)
+    {
+      printf (" ");
+    }
+}
+
+
+void
+debug_print (struct node *nodep, int indent)
+{
+  struct debug_entry   *entp, *p;
+
+  if (nodep == NULL)
+    return;
+
+  entp = get_entry (nodep);
+  if (entp == NULL)
+    return;
+
+  (entp->f)(nodep, indent);
+}
+
+
+void
+print_node (struct node *nodep, int indent)
+{
+  struct debug_entry   *entp, *p;
+
+  if (nodep == NULL)
+    return;
+
+  entp = get_entry (nodep);
+  print_space (indent);
+  printf ("[%s]\n", entp->nicname);
+  if (p = get_entry (nodep->head))
+    {
+      (p->f)(nodep->head, indent + 2);
+    }
+
+  if (p = get_entry (nodep->body))
+    {
+      (p->f)(nodep->body, indent + 2);
+    }
+
+  if (p = get_entry (nodep->next))
+    {
+      (p->f)(nodep->next, indent + 2);
+    }
+}
+
+
+static void
+print_symbol (struct symbol *symbolp, int indent)
+{
+  print_space (indent);
+  printf ("<%s>", symbolp->value);
+}
+
+
+static void
+print_string (struct string *strp, int indent)
+{
+  print_space (indent);
+  printf ("<string>\"%s\"", strp->value);
+}
+
+static void
+print_number (struct number *nump, int indent)
+{
+  print_space (indent);
+  printf ("%d", nump->value);
+}
+
+
+static void
+print_declare (struct node *nodep, int indent)
+{
+  struct symbol        *sp;
+  struct number *np;
+
+  sp = nodep->head;
+  print_space (indent);
+  printf ("[declare]\n");
+  debug_print (nodep->head, indent + 10);
+  if (nodep->next)
+    {
+      print_declare (nodep->next, indent);
+    }
+}
+
+static void
+print_const (struct node *nodep, int indent)
+{
+  struct symbol        *sp;
+  struct number *np;
+
+  sp = nodep->head;
+  np = nodep->body;
+  print_space (indent);
+  printf ("[const]\t%s,%d\n", sp->value, np->value);
+  if (nodep->next)
+    {
+      print_const (nodep->next, indent);
+    }
+}
+
+static void
+print_func (struct node *nodep, int indent)
+{
+  struct symbol        *sp;
+  struct nodep *argp;
+  struct nodep  *exp;
+
+  sp = nodep->head;
+  argp = nodep->body;
+  exp = nodep->next;
+
+  print_space (indent);
+  printf ("[function] %s\n", sp->value);
+  debug_print ((void *)argp, indent + 2);
+  debug_print ((void *)exp, indent + 2);
+/*  printf ("\n"); ** */
+}
+
+static void
+print_proc (struct node *nodep, int indent)
+{
+  struct symbol        *sp;
+  struct nodep *argp;
+  struct nodep  *body;
+
+  sp = nodep->head;
+  argp = nodep->body;
+  body = nodep->next;
+
+  print_space (indent);
+  printf ("[procedure] %s\n", sp->value);
+  debug_print ((void *)argp, indent + 2);
+  debug_print ((void *)body, indent + 2);
+}
+
+
+static void
+print_call (struct node *nodep, int indent)
+{
+  struct symbol        *sp;
+  struct node  *argp;
+
+  sp = nodep->head;
+  argp = nodep->body;
+
+  print_space (indent);
+  printf ("[call] %s(", sp->value);
+  print_args ((void *)argp, indent + 2);
+  printf (")");
+}
+
+
+static void
+print_arglist (struct node *nodep, int indent)
+{
+  print_space (indent);
+  printf ("[args] ");
+  print_args (nodep, indent);
+  printf ("\n");
+}
+
+
+static void
+print_args (struct node *nodep, int indent)
+{
+  struct symbol        *sp;
+  struct node  *argp;
+
+  if (nodep == NULL)
+    return;
+
+  sp = nodep->head;
+  argp = nodep->next;
+  if (sp->type == TK_SYMBOL)
+    {
+      printf ("%s", sp->value);
+    }
+  else
+    {
+      debug_print ((struct node *)sp, 0);
+    }
+
+  if (argp)
+    {
+      printf (", ");
+      print_args (argp, indent);
+    }
+}
+
+static void
+print_expr (struct node *nodep, int indent)
+{
+  struct debug_entry   *entp;
+  struct node          *ex1, *ex2;
+
+  ex1 = nodep->head;
+  ex2 = nodep->body;
+  entp = get_entry (nodep);
+
+  print_space (indent);
+  printf ("(%s", entp->nicname);
+  if (ex1)
+    {
+      printf (" ");
+      debug_print (ex1, 0);
+    }
+  if (ex2)
+    {
+      printf (" ");
+      debug_print (ex2, 0);
+    }
+  printf (")");
+}
+
+
+static void
+print_statement (struct node *nodep, int indent)
+{
+  struct debug_entry   *entp;
+  struct node          *body, *next;
+
+  body = nodep->head;
+  next = nodep->next;
+  entp = get_entry (nodep);
+
+  print_space (indent);
+  printf ("[S] ");
+  if (body)
+    {
+      switch (body->type)
+       {
+       case OP_IF:
+       case OP_WHILE:
+       case OP_SWITCHON:
+       case OP_REPEATUNTIL:
+       case OP_BLOCK:
+         debug_print (body, indent);
+         break;
+
+       default:
+         debug_print (body, 0);
+         printf ("\n");
+         break;
+       }
+    }
+  if (next)
+    {
+      debug_print (next, indent);
+    }
+}
+
+
+static void
+print_variable (struct node *nodep, int indent)
+{
+  struct debug_entry   *entp;
+  struct symbol                *body;
+  struct node          *next;
+
+  body = nodep->head;
+  next = nodep->next;
+  entp = get_entry (nodep);
+
+  print_space (indent);
+  printf ("[Var] ");
+  if (body)
+    {
+      if (body->type == TK_SYMBOL)
+       {
+         printf ("%s", body->value);
+       }
+      else
+       {
+         debug_print ((struct node *)body, 0);
+       }
+    }
+  if (next)
+    {
+      printf (", ");
+      print_args (next, 0);
+    }
+}
+
+
+static void
+print_assign (struct node *nodep, int indent)
+{
+  struct node          *body, *head;
+
+  head = nodep->head;
+  body = nodep->body;
+  print_space (indent);
+  printf ("[assign] ");
+  if (head)
+    {
+      debug_print (head, 0);
+    }
+
+  printf (" := ");
+
+  if (body)
+    {
+      debug_print (body, 0);
+    }
+}
+
+
+static void
+print_return (struct node *nodep, int indent)
+{
+  struct node          *body;
+
+  body = nodep->head;
+  print_space (indent);
+  printf ("[return] ");
+  if (body)
+    {
+      debug_print (body, 0);
+    }
+}
+
+
+static void
+print_initialized_variable (struct node *nodep, int indent)
+{
+  struct node          *body, *next;
+
+  body = nodep->head;
+  next = nodep->body;
+
+  print_space (indent);
+  if (body)
+    {
+      print_variable (body, 0);
+    }
+
+  if (next)
+    {
+      printf (" = ");
+      print_initial_list (next);
+    }
+}
+
+
+static void
+print_initial_list (struct node *nodep)
+{
+  struct number        *nump;
+
+  if (nodep == NULL)
+    return;
+
+  nump = nodep->head;
+  if (nump->type == TK_NUMBER)
+    {
+      printf ("%d", nump->value);
+    }
+  else
+    {
+      print_node ((struct node *)nump, 0);
+    }
+
+  if (nodep->next)
+    {
+      printf (", ");
+      print_initial_list (nodep->next);
+    }
+}
+
+static void
+print_if (struct node *nodep, int indent)
+{
+  struct node  *head, *body;
+  
+  printf ("[IF]  ( ");
+  head = nodep->head;
+  body = nodep->body;
+  debug_print ((struct node *)head, 0);
+  printf (" ) \n");
+  debug_print ((struct node *)body, indent + 4);
+}
+
+
+static void
+print_while (struct node *nodep, int indent)
+{
+  struct node  *head, *body;
+  
+  printf ("[WHILE]  ( ");
+  head = nodep->head;
+  body = nodep->body;
+  debug_print ((struct node *)head, 0);
+  printf (" )\n");
+  debug_print ((struct node *)body, indent + 4);
+}
+
+
+static void
+print_switchon (struct node *nodep, int indent)
+{
+  struct node  *expr, *caselist;
+  
+  printf ("[SWITCHON] ( ");
+  expr = nodep->head;
+  caselist = nodep->body;
+
+  debug_print (expr, 0);
+  printf (" )\n");
+  debug_print (caselist, indent + 4);
+}
+
+
+static void
+print_case (struct node *nodep, int indent)
+{
+  print_space (indent);
+  printf ("[CASE]  ( ");
+  debug_print (nodep->head, 0);
+  printf (" )\n");
+  debug_print (nodep->body, indent + 8);
+  if (nodep->next)
+    {
+      print_case (nodep->next, indent);
+    }
+}
+
+static void
+print_repeatuntil (struct node *nodep, int indent)
+{
+  struct node  *head, *body;
+  
+  printf ("[REEATUNTIL]  ( ");
+  head = nodep->head;
+  body = nodep->body;
+  debug_print ((struct node *)body, 0);
+  printf (" )\n");
+  debug_print ((struct node *)head, indent + 4);
+}
+
+static void
+print_get (struct node *nodep, int indent)
+{
+  print_space (indent);
+  printf ("[GET] ");
+  debug_print ((struct node *)nodep->body, 0);
+  printf ("\n\n");
+}
+
+static void
+print_block (struct node *nodep, int indent)
+{
+  printf ("[BLOCK]\n");
+  debug_print ((struct node *)nodep->head, indent + 4);
+  printf ("\n");
+}
+
+
diff --git a/compiler/lexical.l b/compiler/lexical.l
new file mode 100644 (file)
index 0000000..4e227b7
--- /dev/null
@@ -0,0 +1,130 @@
+%{
+
+#include "bcpl.h"
+#include "parser.tab.h"
+
+char string_buf[MAX_STRING_LENGTH];
+char *string_buf_ptr;
+
+#define yylex  zzlex
+
+%}
+
+%x STRING
+
+%%
+
+
+[\t ]+                         /* ignore */
+
+\/\/.*\n                       { nlcount++; /* (comment) */ }
+
+MANIFEST                       { return (TK_MANIFEST); }
+GLOBAL                         { return (TK_GLOBAL); }
+STATIC                         { return (TK_STATIC); }
+LET                            { return (TK_LET); }
+BE                             { return (TK_BE); }
+RETURN                         { return (TK_RETURN); }
+VALOF                          { return (TK_VALOF); }
+WHILE                          { return (TK_WHILE); }
+IF                             { return (TK_IF); }
+RESULTIS                       { return (TK_RESULTIS); }
+DO                             { return (TK_DO); }
+THEN                           { return (TK_DO); }
+SWITCHON                       { return (TK_SWITCHON); }
+CASE                           { return (TK_CASE); }
+CASEEND                                { return (TK_CASEEND); }
+INTO                           { return (TK_INTO); }
+REPEATUNTIL                    { return (TK_REPEATUNTIL); }
+GET                            { return (TK_GET); }
+AND                            { return (TK_AND); }
+
+#[0-7]+                                { yylval.numberp = make_number (&yytext[1], 8); return (TK_NUMBER); }
+#X[0-9A-Fa-f]+                 { yylval.numberp = make_number (&yytext[2], 16); return (TK_NUMBER); }
+[0-9]+                         { yylval.numberp = make_number (yytext, 10); return (TK_NUMBER); }
+
+","                            { return (TK_COMMA); }
+"$("                           { return (TK_BEGIN); }
+"$)"                           { return (TK_END); }
+"$("[a-zA-Z]+                  { return (TK_BEGIN); }
+"$)"[a-zA-Z]+                  { return (TK_END); }
+":="                           { return (TK_ASSIGN); }
+":"                            { return (TK_COLON); }
+";"                            { return (TK_SEMICOLON); }
+"="                            { return (TK_EQUAL); }
+"*"                            { return (TK_MULTOP); }
+"/"                            { return (TK_DIVOP); }
+"+"                            { return (TK_PLUSOP); }
+"-"                            { return (TK_SUBOP); }
+">"                            { return (TK_LT); }
+">="                           { return (TK_LE); }
+"<"                            { return (TK_GT); }
+"<="                           { return (TK_GE); }
+"&"                            { return (TK_ANDOP); }
+"|"                            { return (TK_OROP); }
+"!"                            { return (TK_VECIS); }
+")"                            { return (TK_RP); }
+"("                            { return (TK_LP); }
+
+\"                             { string_buf_ptr = string_buf; BEGIN(STRING); }
+
+
+<STRING>\"                     { /* saw closing quote - all done */
+                                  BEGIN(INITIAL);
+                                  *string_buf_ptr = '\0';
+                                  /* return string constant token type and
+                                   * value to parser
+                                   */
+                                  yylval.stringp = make_string (string_buf);
+                                  return (TK_STRING);
+                               }
+
+<STRING>\n                     {
+                                  /* error - unterminated string constant */
+                                  /* generate error message */
+                                  fprintf (stderr, "string unterminated.\n");
+                                  exit (0);
+                               }
+
+<STRING>\\[0-7]{1,3}           {
+                               /* octal escape sequence */
+                               int result;
+
+                               (void) sscanf( yytext + 1, "%o", &result );
+
+                               if ( result > 0xff )
+                                 {
+                                         fprintf (stderr, "range over for escape\n");
+                                        /* error, constant is out-of-bounds */
+                                 }
+
+                               *string_buf_ptr++ = result;
+                               }
+
+<STRING>\\[0-9]+               {
+                                 /* generate error - bad escape sequence; something
+                                 * like '\48' or '\0777777'
+                                 */
+                               }
+
+<STRING>"*N"                   { *string_buf_ptr++ = '\n'; }
+<STRING>"*T"                   { *string_buf_ptr++ = '\t'; }
+<STRING>"*R"                   { *string_buf_ptr++ = '\r'; }
+<STRING>"**"                   { *string_buf_ptr++ = '*'; }
+
+<STRING>"*n"                   { *string_buf_ptr++ = yytext[1]; }
+
+<STRING>[^\\\n\"]+             {
+                                 char *yptr = yytext;
+                                 while ( *yptr )
+                                       *string_buf_ptr++ = *yptr++;
+                               }
+
+
+[a-zA-Z\.][a-zA-Z\.0-9]*       { yylval.symbolp = make_symbol (yytext); return TK_SYMBOL; }
+
+
+\n                             { nlcount++; }
+
+
+%%
diff --git a/compiler/main.c b/compiler/main.c
new file mode 100644 (file)
index 0000000..307d2b3
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *
+ */
+
+#include "bcpl.h"
+
+int    nlcount;
+
+
+int
+main (int ac, char **av)
+{
+  extern struct node   *noderoot;
+  extern FILE          *yyin;
+
+  nlcount = 1;
+
+  /* option check... */
+  if (ac < 2)
+    {
+      fprintf (stderr, "usage: %s files...\n", av[0]);
+      exit (0);
+    }
+
+  /* input file setup... */
+  yyin = fopen (av[1], "r");
+  if (yyin == NULL)
+    {
+      fprintf (stderr, "Can not open source file (%s)\n", av[1]);
+      exit (0);
+    }
+
+  if (yyparse () == 1)
+    {
+      printf ("syntax error: compiler stop.\n");
+      exit (0);
+    }
+
+  debug_print (noderoot, 0);
+
+  make_code ();
+}
+
+
+yyerror ()
+{
+  extern char *yytext;
+
+  fprintf (stderr, "line %d: syntax error\n", nlcount);
+  fprintf (stderr, "yytext: %s\n", yytext);
+}
+
diff --git a/compiler/makecode.c b/compiler/makecode.c
new file mode 100644 (file)
index 0000000..04841cd
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ *
+ */
+
+#include "bcpl.h"
+
+make_code ()
+{
+}
diff --git a/compiler/misc.c b/compiler/misc.c
new file mode 100644 (file)
index 0000000..b5a1798
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ *
+ */
+
+
+#include "bcpl.h"
+#include "parser.tab.h"
+
+extern char    *yytext;
+
+struct symbol *
+make_symbol (char *sym)
+{
+  struct symbol        *p;
+
+  p = (struct symbol *)calloc (sizeof (struct symbol), 1);
+  if (p == NULL)
+    {
+      return (NULL);
+    }
+
+  p->type = TK_SYMBOL;
+  p->hash = NULL;
+  p->length = strlen (sym);
+  p->value = strdup (sym);
+  return (p);
+}
+
+
+struct number *
+make_number (char *s, int base)
+{
+  struct number        *p;
+  int          n;
+
+  if (base == 10)
+    n = atoi (s);
+  else if (base == 8)
+    sscanf (s, "%o", &n);
+  else if (base == 16)
+    sscanf (s, "%x", &n);
+
+  p = (struct number *)calloc (sizeof (struct number), 1);
+  if (p == NULL)
+    {
+      return (NULL);
+    }
+  p->type = TK_NUMBER;
+  p->value = n;
+  return (p);
+}
+
+struct string *
+make_string (char *s)
+{
+  struct string        *p;
+
+  p = (struct string *)calloc (sizeof (struct string), 1);
+  if (p == NULL)
+    {
+      return (NULL);
+    }
+
+  p->type = TK_STRING;
+  p->length = strlen (s);
+  p->value = strdup (s);
+  return (p);
+}
+
+
+struct node *
+make_node (int type, void *a, void *b, void *c)
+{
+  struct node  *p;
+
+  p = (struct node *)calloc (sizeof (struct node), 1);
+  if (p == NULL)
+    {
+      return (NULL);
+    }
+
+  p->type = type;
+  p->head = a;
+  p->body = b;
+  p->next = c;
+  return (p);
+}
+
+\f
+static char    *tag_stack[MAX_TAG];
+int            tag_stack_top = 0;
+
+int
+yylex ()
+{
+  int  token;
+  static char  tag[MAX_STRING_LENGTH];
+  char         tmptag[MAX_STRING_LENGTH];
+
+  printf ("yylex\n");
+start:  
+  if (tag[0] != '\0')
+    {
+      if (pop_tag (tmptag) == -1)
+       {
+         printf ("pop_tag error\n");
+         return (-1);
+       }
+
+      if (strcmp (tag, tmptag) == 0)
+       {
+         tag[0] = '\0';
+       }
+      printf ("return TK_END\n");
+      return (TK_END);
+    }
+
+  token = zzlex ();
+  if (token == TK_BEGIN)
+    {
+      if (yytext[2] != '\0')
+       {
+         printf ("PUSH: tag: \"$(%s\"\n", &yytext[2]); 
+         push_tag (&yytext[2]);
+       }
+    }
+  else if (token == TK_END)
+    {
+      if (yytext[2] != '\0')
+       {
+         if (check_tag (&yytext[2]) < 0)
+           {
+             /* error -- not found tag. */
+           }
+         else
+           {
+             strcpy (tag, &yytext[2]);
+             printf ("tag is found. \"%s\"\n", tag);
+             goto start;
+           }
+       }
+    }
+  return (token);
+}
+
+
+int
+check_tag (char *tag)
+{
+  int  i;
+
+  for (i = 0; i < tag_stack_top; i++)
+    {
+      if (strcmp (tag, tag_stack[i]) == 0)
+       {
+         return (i);
+       }
+    }
+  return (-1);
+}
+
+int
+push_tag (char *tag)   
+{
+  tag_stack[tag_stack_top] = strdup (tag);
+  tag_stack_top++;
+  return (tag_stack_top);
+}
+
+
+int
+pop_tag (char tag[])
+{
+  if (tag_stack_top == 0)
+    {
+      return (-1);
+    }
+
+  strcpy (tag, tag_stack[tag_stack_top - 1]);
+  free (tag_stack[tag_stack_top - 1]);
+  tag_stack_top--;
+  return (tag_stack_top);
+}
diff --git a/compiler/parser.y b/compiler/parser.y
new file mode 100644 (file)
index 0000000..722027c
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 1999 Ryuichi Naitoh
+ *
+ *
+ */
+
+/* $Id* */
+%{
+
+#include "bcpl.h"
+
+struct node    *noderoot;
+
+%}
+
+%union{
+  struct symbol                *symbolp;
+  struct string                *stringp;
+  struct character     *character;
+  struct node          *nodep;
+  struct number                *numberp;
+};
+
+
+%token TK_BEGIN
+%token TK_END
+%token TK_EQUAL
+%token TK_COMMA
+%token TK_GLOBAL
+%token TK_COLON
+%token TK_MULTOP
+%token TK_DIVOP
+%token TK_PLUSOP
+%token TK_SUBOP
+%token TK_RP TK_LP
+%token TK_SEMICOLON
+%token TK_ASSIGN
+%token TK_GT                   /* < */
+%token TK_LT                   /* > */
+%token TK_GE                   /* <= */
+%token TK_LE                   /* >= */
+%token TK_ANDOP                        /* & */
+%token TK_OROP                 /* | */
+%token TK_VECIS                        /* ! */
+
+/* Í½Ìó¸ì : 'TK_' ¤òºï¤Ã¤¿»Ä¤ê¤¬Í½Ìó¸ì¤ÈÅù¤·¤¤ */
+%token TK_MANIFEST
+%token TK_AND
+%token TK_LET
+%token TK_VALOF
+%token TK_RETURN
+%token TK_BE
+%token TK_IF
+%token TK_WHILE
+%token TK_DO
+%token TK_UNLESS
+%token TK_TEST
+%token TK_UNTIL
+%token TK_STATIC
+%token TK_RESULTIS
+%token TK_FOR
+%token TK_SWITCHON
+%token TK_CASE
+%token TK_CASEEND
+%token TK_INTO
+%token TK_REPEATUNTIL
+%token TK_GET
+
+%token <symbolp>TK_SYMBOL
+%token <stringp>TK_STRING
+%token <numberp>TK_NUMBER
+
+%type <nodep>program
+%type <nodep>declare.list
+%type <nodep>declare.manifest
+%type <nodep>manifest.list
+%type <nodep>declare.global
+%type <nodep>global.list
+%type <nodep>declare.function
+%type <nodep>argument.list argument
+%type <nodep>expression
+%type <nodep>declare.procedure
+%type <nodep>statement.list
+%type <nodep>statement
+%type <nodep>call.function
+%type <nodep>expression.list
+%type <nodep>declare.variable.list
+%type <nodep>declare.variable
+%type <nodep>declare.get
+%type <nodep>initialize.list
+%type <nodep>if.head if.statement
+%type <nodep>while.statement
+%type <nodep>declare.static
+%type <nodep>switchon.statement
+%type <nodep>case.statement.list
+%type <nodep>repeatuntil.statement
+
+
+%right TK_ASSIGN
+%left TK_ANDOP TK_OROP
+%left TK_PLUSOP TK_SUBOP
+%left TK_MULTOP TK_DIVOP TK_GT TK_LT TK_GE TK_LE TK_EQUAL TK_VECIS
+%left TK_NUMBER TK_SYMBOL
+
+
+%start program
+
+%%
+
+program
+       : declare.list                          { noderoot = $1; }
+
+declare.list
+       : /* empty */                           { $$ = NULL; }
+       | declare.manifest declare.list         { $$ = make_node (OP_DECLARE, $1, NULL, $2); }
+       | declare.global declare.list           { $$ = make_node (OP_DECLARE, $1, NULL, $2); }
+       | declare.function declare.list         { $$ = make_node (OP_DECLARE, $1, NULL, $2); }
+       | declare.procedure declare.list        { $$ = make_node (OP_DECLARE, $1, NULL, $2); }
+       | declare.static declare.list           { $$ = make_node (OP_DECLARE, $1, NULL, $2); }
+       | declare.get declare.list              { $$ = make_node (OP_DECLARE, $1, NULL, $2); }
+       ;
+
+declare.manifest
+       : TK_MANIFEST TK_BEGIN manifest.list TK_END
+                                               { $$ = make_node (OP_MANIFEST, $3, NULL, NULL);
+                                               }
+
+manifest.list
+       : /* empty */                           { $$ = NULL; }
+       | TK_SYMBOL TK_EQUAL TK_NUMBER          { $$ = make_node (OP_CONST, $1, $3, NULL); }
+       ;
+       | TK_SYMBOL TK_EQUAL TK_NUMBER TK_COMMA manifest.list 
+                                               { $$ = make_node (OP_CONST, $1, $3, $5); }
+       ;
+
+declare.global
+       : TK_GLOBAL TK_BEGIN global.list TK_END { $$ = make_node (OP_GLOBAL, $3, NULL, NULL); }
+
+global.list
+       : /* empty */                           { $$ = NULL; }
+       | TK_SYMBOL TK_COLON TK_NUMBER          { $$ = make_node (OP_CONST, $1, $3, NULL); }
+       | TK_SYMBOL TK_COLON TK_NUMBER TK_COMMA global.list
+                                               { $$ = make_node (OP_CONST, $1, $3, $5); }
+       ;
+       
+declare.function
+       : TK_LET TK_SYMBOL argument.list TK_EQUAL expression
+                                               { $$ = make_node (OP_FUNCTION, $2, $3, $5); }
+       ;
+
+declare.procedure
+       : TK_LET TK_SYMBOL argument.list TK_BE TK_BEGIN statement.list TK_END
+                                               { $$ = make_node (OP_PROCEDURE, $2, $3, $6); }
+       | TK_AND TK_SYMBOL argument.list TK_BE TK_BEGIN statement.list TK_END
+                                               { $$ = make_node (OP_PROCEDURE, $2, $3, $6); }
+       ;
+
+declare.static
+       : TK_STATIC TK_BEGIN global.list TK_END
+                                               { $$ = make_node (OP_STATIC, $3, NULL, NULL); }
+       ;
+
+declare.get
+       : TK_GET TK_STRING                      { $$ = make_node (OP_GET, NULL, $2, NULL); }
+       ;
+
+statement.list
+       : /* empty */                           { $$ = NULL; }
+       | statement statement.list              { $$ = make_node (OP_STATEMENT, $1, NULL, $2); }
+       | repeatuntil.statement statement.list  { $$ = make_node (OP_STATEMENT, $1, NULL, $2); }
+       ;
+
+statement
+       : expression TK_SEMICOLON               { $$ = $1; }
+       | declare.variable.list TK_SEMICOLON    { $$ = $1; }
+       | TK_RETURN TK_LP expression TK_RP TK_SEMICOLON
+                                               { $$ = make_node (OP_RETURN, $3, NULL, NULL); }
+       | TK_RESULTIS TK_LP expression TK_RP TK_SEMICOLON
+                                               { $$ = make_node (OP_RETURN, $3, NULL, NULL); }
+       | if.statement                          { $$ = $1; }
+       | while.statement                       { $$ = $1; }
+       | switchon.statement                    { $$ = $1; }
+       | TK_BEGIN statement.list TK_END        { $$ = make_node (OP_BLOCK, $2, NULL, NULL); }
+       ;
+
+if.statement
+       : if.head statement                     { $$ = make_node (OP_IF, $1, $2, NULL); }
+       | if.head TK_BEGIN statement.list TK_END
+                                               { $$ = make_node (OP_IF, $1, $3, NULL); }
+       ;
+
+if.head
+       : TK_IF expression TK_DO                { $$ = $2; }
+       ;
+
+while.statement
+       : TK_WHILE expression TK_DO statement   { $$ = make_node (OP_WHILE, $2, $4, NULL); }
+       | TK_WHILE expression TK_DO TK_BEGIN statement.list TK_END
+                                               { $$ = make_node (OP_WHILE, $2, $5, NULL); }
+       ;
+
+switchon.statement
+       : TK_SWITCHON expression TK_INTO TK_BEGIN case.statement.list TK_END { $$ = make_node (OP_SWITCHON, $2, $5, NULL); }
+       ;
+
+case.statement.list
+       : TK_CASE expression TK_COLON statement.list                                     { $$ = make_node (OP_CASECONT, $2, $4, NULL); }
+       | TK_CASE expression TK_COLON statement.list TK_CASEEND                          { $$ = make_node (OP_CASE, $2, $4, NULL); }
+       | TK_CASE expression TK_COLON statement.list TK_CASEEND case.statement.list { $$ = make_node (OP_CASE, $2, $4, $6); }
+       ;
+
+repeatuntil.statement
+       : TK_BEGIN statement.list TK_END TK_REPEATUNTIL expression { $$ = make_node (OP_REPEATUNTIL, $2, $5, NULL); }
+       ;
+
+declare.variable.list
+       : TK_LET declare.variable               { $$ = $2; }
+       | TK_LET declare.variable TK_EQUAL initialize.list
+                                               { $$ = make_node (OP_INITIALVAR, $2, $4, NULL); }
+       ;
+
+declare.variable
+       : TK_SYMBOL TK_COMMA declare.variable   { $$ = make_node (OP_VARIABLE, $1, NULL, $3); }
+       | TK_SYMBOL                             { $$ = make_node (OP_VARIABLE, $1, NULL, NULL); }
+       ;
+
+initialize.list
+       : TK_NUMBER TK_COMMA initialize.list    { $$ = make_node (OP_CONST_LIST, $1, NULL, $3); }
+       | TK_NUMBER                             { $$ = make_node (OP_CONST_LIST, $1, NULL, NULL); }
+       ;
+
+
+call.function
+       : TK_SYMBOL TK_LP  TK_RP                { $$ = make_node (OP_CALL, $1, NULL, NULL); }
+       | TK_SYMBOL TK_LP expression.list TK_RP { $$ = make_node (OP_CALL, $1, $3, NULL); }
+       ;
+
+argument.list
+       : TK_LP argument TK_RP                  { $$ = $2; }
+       | TK_LP  TK_RP                          { $$ = NULL; }
+       ;
+
+argument
+       : TK_SYMBOL TK_COMMA argument           { $$ = make_node (OP_ARGS, $1, NULL, $3); }
+       | TK_SYMBOL                             { $$ = make_node (OP_ARGS, $1, NULL, NULL); }
+       ;
+
+expression.list
+       : expression TK_COMMA expression.list   { $$ = make_node (OP_ARGS, $1, NULL, $3); }
+       ;
+       | expression                            { $$ = make_node (OP_ARGS, $1, NULL, NULL); }
+       ;
+
+expression
+       : TK_NUMBER                             { $$ = (struct node *)$1; }
+       | TK_SYMBOL                             { $$ = (struct node *)$1; }
+       | TK_VALOF TK_BEGIN statement.list TK_END
+                                               { $$ = make_node (OP_VALOF, $3, NULL, NULL); }
+       | TK_STRING                             { $$ = (struct node *)$1; }
+       | call.function                         { $$ = $1; }
+       | TK_LP expression TK_RP                { $$ = $2; }
+       | expression TK_PLUSOP expression       { $$ = make_node (OP_PLUSOP, $1, $3, NULL); }
+       | expression TK_SUBOP expression        { $$ = make_node (OP_SUBOP, $1, $3, NULL); }
+       | expression TK_MULTOP expression       { $$ = make_node (OP_MULTOP, $1, $3, NULL); }
+       | expression TK_DIVOP expression        { $$ = make_node (OP_DIVOP, $1, $3, NULL); }
+       | expression TK_GT expression           { $$ = make_node (OP_GT, $1, $3, NULL); }
+       | expression TK_LT expression           { $$ = make_node (OP_LT, $1, $3, NULL); }
+       | expression TK_GE expression           { $$ = make_node (OP_GE, $1, $3, NULL); }
+       | expression TK_LE expression           { $$ = make_node (OP_LE, $1, $3, NULL); }
+       | expression TK_ANDOP expression        { $$ = make_node (OP_AND, $1, $3, NULL); }
+       | expression TK_OROP expression         { $$ = make_node (OP_OR, $1, $3, NULL); }
+       | expression TK_EQUAL expression        { $$ = make_node (OP_EQUAL, $1, $3, NULL); }
+       | expression TK_ASSIGN expression       { $$ = make_node (OP_SET, $1, $3, NULL); }
+       | expression TK_VECIS expression        { $$ = make_node (OP_VECIS, $1, $3, NULL); }
+       ;       
+
+%%
diff --git a/example/foo.bcp b/example/foo.bcp
new file mode 100644 (file)
index 0000000..1e29787
--- /dev/null
@@ -0,0 +1,50 @@
+//
+//     bcpl sample program.
+//
+
+GET "STD.H"
+
+MANIFEST $( FOO = 1, 
+           BAR = 2,
+         $)
+
+GLOBAL $( FOO:1, BAR:2 $)
+
+STATIC $( foo: 1 $)
+
+
+LET start (argc, argv) BE
+$(
+       LET     val;
+
+       writef ("program name is %s *N", argv ! 0);
+
+       val = atoi (argv ! 1);
+
+       SWITCHON val INTO
+       $(
+       CASE 1: writef ("value is 1*N");
+               CASEEND
+
+       CASE 2: writef ("value is 2*N");
+               CASEEND
+       $)
+
+       $(
+               writef ("val = %d*N", val);
+               val := val - 1;
+       $) REPEATUNTIL val < 0
+
+       writef ("end.*N");
+$)
+
+AND foo () BE
+$(aa
+       LET     val;
+
+       $(bb
+       val := 1 + 1 * 2;
+       writef ("val = %d*N", val);
+
+
+$)aa
\ No newline at end of file