/* * This file is part of Jehanne. * * Copyright (C) 2016 Giacomo Tesio * * 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 . */ /* * 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 #include #include #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) } }