add parser
authorDavid Schleef <ds@schleef.org>
Sat, 28 Mar 2009 06:58:21 +0000 (23:58 -0700)
committerDavid Schleef <ds@schleef.org>
Sat, 28 Mar 2009 07:06:35 +0000 (00:06 -0700)
orc/Makefile.am
orc/orcparse.c [new file with mode: 0644]
orc/orcparse.h [new file with mode: 0644]

index 3993f9b..82d6e4e 100644 (file)
@@ -22,6 +22,7 @@ liborc_@ORC_MAJORMINOR@_la_SOURCES = \
        orcprogram-sse.c \
        orcprogram.h \
        orcopcodes.c \
+       orcparse.c \
        orcrules-mmx.c \
        orcrules-sse.c \
        orcrules-arm.c \
@@ -54,6 +55,7 @@ pkginclude_HEADERS = \
        orcdebug.h \
        orcprogram.h \
        orcutils.h \
+       orcparse.h \
        opcodes.h \
        x86.h \
        arm.h
diff --git a/orc/orcparse.c b/orc/orcparse.c
new file mode 100644 (file)
index 0000000..6149362
--- /dev/null
@@ -0,0 +1,201 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <orc/orc.h>
+#include <orc/orcparse.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+typedef struct _OrcParser OrcParser;
+struct _OrcParser {
+  const char *code;
+  int code_length;
+
+  const char *p;
+
+  int line_number;
+  char *line;
+  int creg_index;
+
+  OrcOpcodeSet *opcode_set;
+  OrcProgram *program;
+
+  OrcProgram **programs;
+  int n_programs;
+};
+
+static void orc_parse_get_line (OrcParser *parser);
+static OrcStaticOpcode * get_opcode (OrcParser *parser, const char *opcode);
+
+
+int
+orc_parse (const char *code, OrcProgram ***programs)
+{
+  OrcParser _parser;
+  OrcParser *parser = &_parser;
+
+  memset (parser, 0, sizeof(*parser));
+
+  parser->code = code;
+  parser->code_length = strlen (code);
+  parser->line_number = -1;
+  parser->p = code;
+  parser->opcode_set = orc_opcode_set_get ("sys");
+  parser->programs = malloc (sizeof(OrcProgram *)*100);
+
+  while (parser->p[0] != 0) {
+    char *p;
+    char *end;
+    char *token[10];
+    int n_tokens;
+
+    orc_parse_get_line (parser);
+
+    p = parser->line;
+    end = p + strlen (p);
+    //printf("%d: %s\n", parser->line_number, parser->line);
+
+    while (p[0] == ' ' || p[0] == '\t') p++;
+
+    if (p[0] == 0) {
+      continue;
+    }
+
+    if (p[0] == '#') {
+      printf("comment: %s\n", p+1);
+      continue;
+    }
+
+    n_tokens = 0;
+
+    while (p < end) {
+      if (p[0] == ' ' || p[0] == '\t' || p[0] == ',') p++;
+      if (p[0] == 0 || p[0] == '#') break;
+
+      token[n_tokens] = p;
+      while (p[0] != 0 && p[0] != ' ' && p[0] != '\t' && p[0] != ',') p++;
+      n_tokens++;
+
+      p[0] = 0;
+      p++;
+    }
+
+    if (n_tokens == 0) {
+      continue;
+    }
+
+    {
+      int i;
+      for(i=0;i<n_tokens;i++){
+        printf("'%s' ", token[i]);
+      }
+      printf("\n");
+    }
+
+    if (token[0][0] == '.') {
+      if (strcmp (token[0], ".function") == 0) {
+        parser->program = orc_program_new ();
+        orc_program_set_name (parser->program, token[1]);
+        parser->programs[parser->n_programs] = parser->program;
+        parser->n_programs++;
+        parser->creg_index = 1;
+      } else if (strcmp (token[0], ".source") == 0) {
+        int size = strtol (token[1], NULL, 0);
+        orc_program_add_source (parser->program, size, token[2]);
+      } else if (strcmp (token[0], ".dest") == 0) {
+        int size = strtol (token[1], NULL, 0);
+        orc_program_add_destination (parser->program, size, token[2]);
+      } else if (strcmp (token[0], ".temp") == 0) {
+        int size = strtol (token[1], NULL, 0);
+        orc_program_add_temporary (parser->program, size, token[2]);
+      } else if (strcmp (token[0], ".param") == 0) {
+        int size = 2;
+        orc_program_add_parameter (parser->program, size, token[1]);
+      } else {
+        printf("ERROR: unknown directive: %s\n", token[0]);
+      }
+    } else {
+      OrcStaticOpcode *o;
+
+      o = get_opcode (parser, token[0]);
+
+      if (o) {
+        if (n_tokens == 4) {
+          char *end;
+          int imm = strtol (token[3], &end, 0);
+          if (end != token[3]) {
+            char creg[10];
+            sprintf(creg, "c%d", parser->creg_index);
+            parser->creg_index++;
+            orc_program_add_constant (parser->program, 2, imm, creg);
+            orc_program_append_str (parser->program, token[0],
+                token[1], token[2], creg);
+          } else {
+            orc_program_append_str (parser->program, token[0],
+                token[1], token[2], token[3]);
+          }
+        } else {
+          orc_program_append_ds_str (parser->program, token[0],
+              token[1], token[2]);
+        }
+      } else {
+        printf("ERROR: unknown token[0]: %s\n", token[0]);
+      }
+    }
+  }
+
+
+  if (parser->line) free (parser->line);
+
+  *programs = parser->programs;
+  return parser->n_programs;
+}
+
+static OrcStaticOpcode *
+get_opcode (OrcParser *parser, const char *opcode)
+{
+  int i;
+
+  for(i=0;i<parser->opcode_set->n_opcodes;i++){
+    if (strcmp (opcode, parser->opcode_set->opcodes[i].name) == 0) {
+      return parser->opcode_set->opcodes + i;
+    }
+  }
+
+  return NULL;
+}
+
+static void
+orc_parse_get_line (OrcParser *parser)
+{
+  const char *end;
+  int n;
+
+  if (parser->line) {
+    free (parser->line);
+    parser->line = NULL;
+  }
+
+  end = strchr (parser->p, '\n');
+  if (end == NULL) {
+    end = parser->code + parser->code_length;
+  }
+
+  n = end - parser->p;
+  parser->line = malloc (n + 1);
+  memcpy (parser->line, parser->p, n);
+  parser->line[n] = 0;
+
+  parser->p = end;
+  if (parser->p[0] == '\n') {
+    parser->p++;
+  }
+  parser->line_number++;
+}
+
+
diff --git a/orc/orcparse.h b/orc/orcparse.h
new file mode 100644 (file)
index 0000000..c7588be
--- /dev/null
@@ -0,0 +1,14 @@
+
+#ifndef __ORC_PARSE_H__
+#define __ORC_PARSE_H__
+
+#include <orc/orcutils.h>
+
+ORC_BEGIN_DECLS
+
+int orc_parse (const char *code, OrcProgram ***programs);
+
+ORC_END_DECLS
+
+#endif
+