jehanne/sys/src/cmd/awk/maketab.go

190 lines
4.4 KiB
Go

/*
* This file is part of Jehanne.
*
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
*
* Jehanne is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* Jehanne is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* this program makes the table to link function names
* and type indices that is used by execute() in run.c.
* it finds the indices in y.tab.h, produced by yacc.
*/
package main
import (
"bufio"
"log"
"os"
"strings"
"strconv"
"text/template"
)
type Flist struct {
Token string
Name string
Pname string
}
var flist = []Flist {
{ "PROGRAM", "program", "" },
{ "BOR", "boolop", " || " },
{ "AND", "boolop", " && " },
{ "NOT", "boolop", " !" },
{ "NE", "relop", " != " },
{ "EQ", "relop", " == " },
{ "LE", "relop", " <= " },
{ "LT", "relop", " < " },
{ "GE", "relop", " >= " },
{ "GT", "relop", " > " },
{ "ARRAY", "array", "" },
{ "INDIRECT", "indirect", "$(" },
{ "SUBSTR", "substr", "substr" },
{ "SUB", "sub", "sub" },
{ "GSUB", "gsub", "gsub" },
{ "INDEX", "sindex", "sindex" },
{ "SPRINTF", "awksprintf", "sprintf" },
{ "ADD", "arith", " + " },
{ "MINUS", "arith", " - " },
{ "MULT", "arith", " * " },
{ "DIVIDE", "arith", " / " },
{ "MOD", "arith", " % " },
{ "UMINUS", "arith", " -" },
{ "POWER", "arith", " **" },
{ "PREINCR", "incrdecr", "++" },
{ "POSTINCR", "incrdecr", "++" },
{ "PREDECR", "incrdecr", "--" },
{ "POSTDECR", "incrdecr", "--" },
{ "CAT", "cat", " " },
{ "PASTAT", "pastat", "" },
{ "PASTAT2", "dopa2", "" },
{ "MATCH", "matchop", " ~ " },
{ "NOTMATCH", "matchop", " !~ " },
{ "MATCHFCN", "matchop", "matchop" },
{ "INTEST", "intest", "intest" },
{ "PRINTF", "awkprintf", "printf" },
{ "PRINT", "printstat", "print" },
{ "CLOSE", "closefile", "closefile" },
{ "DELETE", "awkdelete", "awkdelete" },
{ "SPLIT", "split", "split" },
{ "ASSIGN", "assign", " = " },
{ "ADDEQ", "assign", " += " },
{ "SUBEQ", "assign", " -= " },
{ "MULTEQ", "assign", " *= " },
{ "DIVEQ", "assign", " /= " },
{ "MODEQ", "assign", " %= " },
{ "POWEQ", "assign", " ^= " },
{ "CONDEXPR", "condexpr", " ?: " },
{ "IF", "ifstat", "if(" },
{ "WHILE", "whilestat", "while(" },
{ "FOR", "forstat", "for(" },
{ "DO", "dostat", "do" },
{ "IN", "instat", "instat" },
{ "NEXT", "jump", "next" },
{ "NEXTFILE", "jump", "nextfile" },
{ "EXIT", "jump", "exit" },
{ "BREAK", "jump", "break" },
{ "CONTINUE", "jump", "continue" },
{ "RETURN", "jump", "ret" },
{ "BLTIN", "bltin", "bltin" },
{ "CALL", "call", "call" },
{ "ARG", "arg", "arg" },
{ "VARNF", "getnf", "NF" },
{ "GETLINE", "getline", "getline" },
{ "", "", "" },
}
type Proctab struct {
Code int
Name string
Func string
}
func getf(token string) Flist {
for i := range flist {
if token == flist[i].Token {
return flist[i]
}
}
return Flist{"","nullproc",""}
}
func main() {
file, err := os.Open("y.tab.h")
if err != nil {
log.Fatal(err)
}
defer file.Close()
proctab := make([]Proctab, 0)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
s := scanner.Text()
if strings.Contains(s, "#define") {
tokens := strings.Split(s, " ");
i, err := strconv.Atoi(tokens[2])
if err == nil {
f := getf(tokens[1])
proctab = append(proctab, Proctab{i, tokens[1], f.Name})
}
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
tmpl, err := template.New("proctab.c").Parse(`/* automatically generated by maketab */
#include <u.h>
#include <lib9.h>
#include <bio.h>
#include "awk.h"
#include "y.tab.h"
static char *printname[{{len .}}] = {
{{ range . }} (char *) "{{.Name}}", /* {{.Code}} */
{{ end }}
};
Cell *(*proctab[{{len .}}])(Node **, int) = {
{{ range . }} {{.Func}}, /* {{.Name}} */
{{ end }}
};
char *
tokname(int n)
{
static char buf[100];
if (n < FIRSTTOKEN || n > LASTTOKEN) {
sprint(buf, "token %d", n);
return buf;
}
return printname[n-FIRSTTOKEN];
}
`)
if err != nil {
log.Fatal(err)
}
err = tmpl.Execute(os.Stdout, proctab)
if err != nil {
log.Fatal(err)
}
}