// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "a.h"

/*
 * Translate a .goc file into a .c file.  A .goc file is a combination
 * of a limited form of Go with C.
 */

/*
	package PACKAGENAME
	{# line}
	func NAME([NAME TYPE { , NAME TYPE }]) [(NAME TYPE { , NAME TYPE })] \{
	  C code with proper brace nesting
	\}
*/

/*
 * We generate C code which implements the function such that it can
 * be called from Go and executes the C code.
 */

static char *input;
static Buf *output;
#define EOF -1

static int
xgetchar(void)
{
	int c;
	
	c = *input;
	if(c == 0)
		return EOF;
	input++;
	return c;
}

static void
xungetc(void)
{
	input--;
}

static void
xputchar(char c)
{
	bwrite(output, &c, 1);
}

static int
xisspace(int c)
{
	return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}

/* Whether we're emitting for gcc */
static int gcc;

/* File and line number */
static const char *file;
static unsigned int lineno = 1;

/* List of names and types.  */
struct params {
	struct params *next;
	char *name;
	char *type;
};

/* index into type_table */
enum {
	Bool,
	Float,
	Int,
	Uint,
	Uintptr,
	String,
	Slice,
	Eface,
};

static struct {
	char *name;
	int size;
} type_table[] = {
	/* variable sized first, for easy replacement */
	/* order matches enum above */
	/* default is 32-bit architecture sizes */
	{"bool",		1},
	{"float",	4},
	{"int",		4},
	{"uint",		4},
	{"uintptr",	4},
	{"String",	8},
	{"Slice",	12},
	{"Eface",	8},

	/* fixed size */
	{"float32",	4},
	{"float64",	8},
	{"byte",		1},
	{"int8",		1},
	{"uint8",	1},
	{"int16",	2},
	{"uint16",	2},
	{"int32",	4},
	{"uint32",	4},
	{"int64",	8},
	{"uint64",	8},

	{nil},
};

/* Fixed structure alignment (non-gcc only) */
int structround = 4;

/* Unexpected EOF.  */
static void
bad_eof(void)
{
	fatal("%s:%ud: unexpected EOF\n", file, lineno);
}

/* Free a list of parameters.  */
static void
free_params(struct params *p)
{
	while (p != nil) {
		struct params *next;

		next = p->next;
		xfree(p->name);
		xfree(p->type);
		xfree(p);
		p = next;
	}
}

/* Read a character, tracking lineno.  */
static int
getchar_update_lineno(void)
{
	int c;

	c = xgetchar();
	if (c == '\n')
		++lineno;
	return c;
}

/* Read a character, giving an error on EOF, tracking lineno.  */
static int
getchar_no_eof(void)
{
	int c;

	c = getchar_update_lineno();
	if (c == EOF)
		bad_eof();
	return c;
}

/* Read a character, skipping comments.  */
static int
getchar_skipping_comments(void)
{
	int c;

	while (1) {
		c = getchar_update_lineno();
		if (c != '/')
			return c;

		c = xgetchar();
		if (c == '/') {
			do {
				c = getchar_update_lineno();
			} while (c != EOF && c != '\n');
			return c;
		} else if (c == '*') {
			while (1) {
				c = getchar_update_lineno();
				if (c == EOF)
					return EOF;
				if (c == '*') {
					do {
						c = getchar_update_lineno();
					} while (c == '*');
					if (c == '/')
						break;
				}
			}
		} else {
			xungetc();
			return '/';
		}
	}
}

/*
 * Read and return a token.  Tokens are string or character literals
 * or else delimited by whitespace or by [(),{}].
 * The latter are all returned as single characters.
 */
static char *
read_token(void)
{
	int c, q;
	char *buf;
	unsigned int alc, off;
	char* delims = "(),{}";

	while (1) {
		c = getchar_skipping_comments();
		if (c == EOF)
			return nil;
		if (!xisspace(c))
			break;
	}
	alc = 16;
	buf = xmalloc(alc + 1);
	off = 0;
	if(c == '"' || c == '\'') {
		q = c;
		buf[off] = c;
		++off;
		while (1) {
			if (off+2 >= alc) { // room for c and maybe next char
				alc *= 2;
				buf = xrealloc(buf, alc + 1);
			}
			c = getchar_no_eof();
			buf[off] = c;
			++off;
			if(c == q)
				break;
			if(c == '\\') {
				buf[off] = getchar_no_eof();
				++off;
			}
		}
	} else if (xstrrchr(delims, c) != nil) {
		buf[off] = c;
		++off;
	} else {
		while (1) {
			if (off >= alc) {
				alc *= 2;
				buf = xrealloc(buf, alc + 1);
			}
			buf[off] = c;
			++off;
			c = getchar_skipping_comments();
			if (c == EOF)
				break;
			if (xisspace(c) || xstrrchr(delims, c) != nil) {
				if (c == '\n')
					lineno--;
				xungetc();
				break;
			}
		}
	}
	buf[off] = '\0';
	return buf;
}

/* Read a token, giving an error on EOF.  */
static char *
read_token_no_eof(void)
{
	char *token = read_token();
	if (token == nil)
		bad_eof();
	return token;
}

/* Read the package clause, and return the package name.  */
static char *
read_package(void)
{
	char *token;

	token = read_token_no_eof();
	if (token == nil)
		fatal("%s:%ud: no token\n", file, lineno);
	if (!streq(token, "package")) {
		fatal("%s:%ud: expected \"package\", got \"%s\"\n",
			file, lineno, token);
	}
	return read_token_no_eof();
}

/* Read and copy preprocessor lines.  */
static void
read_preprocessor_lines(void)
{
	while (1) {
		int c;

		do {
			c = getchar_skipping_comments();
		} while (xisspace(c));
		if (c != '#') {
			xungetc();
			break;
		}
		xputchar(c);
		do {
			c = getchar_update_lineno();
			xputchar(c);
		} while (c != '\n');
	}
}

/*
 * Read a type in Go syntax and return a type in C syntax.  We only
 * permit basic types and pointers.
 */
static char *
read_type(void)
{
	char *p, *op, *q;
	int pointer_count;
	unsigned int len;

	p = read_token_no_eof();
	if (*p != '*')
		return p;
	op = p;
	pointer_count = 0;
	while (*p == '*') {
		++pointer_count;
		++p;
	}
	len = xstrlen(p);
	q = xmalloc(len + pointer_count + 1);
	xmemmove(q, p, len);
	while (pointer_count > 0) {
		q[len] = '*';
		++len;
		--pointer_count;
	}
	q[len] = '\0';
	xfree(op);
	return q;
}

/* Return the size of the given type. */
static int
type_size(char *p)
{
	int i;

	if(p[xstrlen(p)-1] == '*')
		return type_table[Uintptr].size;

	for(i=0; type_table[i].name; i++)
		if(streq(type_table[i].name, p))
			return type_table[i].size;
	fatal("%s:%ud: unknown type %s\n", file, lineno, p);
	return 0;
}

/*
 * Read a list of parameters.  Each parameter is a name and a type.
 * The list ends with a ')'.  We have already read the '('.
 */
static struct params *
read_params(int *poffset)
{
	char *token;
	struct params *ret, **pp, *p;
	int offset, size, rnd;

	ret = nil;
	pp = &ret;
	token = read_token_no_eof();
	offset = 0;
	if (!streq(token, ")")) {
		while (1) {
			p = xmalloc(sizeof(struct params));
			p->name = token;
			p->type = read_type();
			p->next = nil;
			*pp = p;
			pp = &p->next;

			size = type_size(p->type);
			rnd = size;
			if(rnd > structround)
				rnd = structround;
			if(offset%rnd)
				offset += rnd - offset%rnd;
			offset += size;

			token = read_token_no_eof();
			if (!streq(token, ","))
				break;
			token = read_token_no_eof();
		}
	}
	if (!streq(token, ")")) {
		fatal("%s:%ud: expected '('\n",
			file, lineno);
	}
	if (poffset != nil)
		*poffset = offset;
	return ret;
}

/*
 * Read a function header.  This reads up to and including the initial
 * '{' character.  Returns 1 if it read a header, 0 at EOF.
 */
static int
read_func_header(char **name, struct params **params, int *paramwid, struct params **rets)
{
	int lastline;
	char *token;

	lastline = -1;
	while (1) {
		token = read_token();
		if (token == nil)
			return 0;
		if (streq(token, "func")) {
			if(lastline != -1)
				bwritef(output, "\n");
			break;
		}
		if (lastline != lineno) {
			if (lastline == lineno-1)
				bwritef(output, "\n");
			else
				bwritef(output, "\n#line %d \"%s\"\n", lineno, file);
			lastline = lineno;
		}
		bwritef(output, "%s ", token);
	}

	*name = read_token_no_eof();

	token = read_token();
	if (token == nil || !streq(token, "(")) {
		fatal("%s:%ud: expected \"(\"\n",
			file, lineno);
	}
	*params = read_params(paramwid);

	token = read_token();
	if (token == nil || !streq(token, "("))
		*rets = nil;
	else {
		*rets = read_params(nil);
		token = read_token();
	}
	if (token == nil || !streq(token, "{")) {
		fatal("%s:%ud: expected \"{\"\n",
			file, lineno);
	}
	return 1;
}

/* Write out parameters.  */
static void
write_params(struct params *params, int *first)
{
	struct params *p;

	for (p = params; p != nil; p = p->next) {
		if (*first)
			*first = 0;
		else
			bwritef(output, ", ");
		bwritef(output, "%s %s", p->type, p->name);
	}
}

/* Write a 6g function header.  */
static void
write_6g_func_header(char *package, char *name, struct params *params,
		     int paramwid, struct params *rets)
{
	int first, n;

	bwritef(output, "void\n%s·%s(", package, name);
	first = 1;
	write_params(params, &first);

	/* insert padding to align output struct */
	if(rets != nil && paramwid%structround != 0) {
		n = structround - paramwid%structround;
		if(n & 1)
			bwritef(output, ", uint8");
		if(n & 2)
			bwritef(output, ", uint16");
		if(n & 4)
			bwritef(output, ", uint32");
	}

	write_params(rets, &first);
	bwritef(output, ")\n{\n");
}

/* Write a 6g function trailer.  */
static void
write_6g_func_trailer(struct params *rets)
{
	struct params *p;

	for (p = rets; p != nil; p = p->next)
		bwritef(output, "\tFLUSH(&%s);\n", p->name);
	bwritef(output, "}\n");
}

/* Define the gcc function return type if necessary.  */
static void
define_gcc_return_type(char *package, char *name, struct params *rets)
{
	struct params *p;

	if (rets == nil || rets->next == nil)
		return;
	bwritef(output, "struct %s_%s_ret {\n", package, name);
	for (p = rets; p != nil; p = p->next)
		bwritef(output, "  %s %s;\n", p->type, p->name);
	bwritef(output, "};\n");
}

/* Write out the gcc function return type.  */
static void
write_gcc_return_type(char *package, char *name, struct params *rets)
{
	if (rets == nil)
		bwritef(output, "void");
	else if (rets->next == nil)
		bwritef(output, "%s", rets->type);
	else
		bwritef(output, "struct %s_%s_ret", package, name);
}

/* Write out a gcc function header.  */
static void
write_gcc_func_header(char *package, char *name, struct params *params,
		      struct params *rets)
{
	int first;
	struct params *p;

	define_gcc_return_type(package, name, rets);
	write_gcc_return_type(package, name, rets);
	bwritef(output, " %s_%s(", package, name);
	first = 1;
	write_params(params, &first);
	bwritef(output, ") asm (\"%s.%s\");\n", package, name);
	write_gcc_return_type(package, name, rets);
	bwritef(output, " %s_%s(", package, name);
	first = 1;
	write_params(params, &first);
	bwritef(output, ")\n{\n");
	for (p = rets; p != nil; p = p->next)
		bwritef(output, "  %s %s;\n", p->type, p->name);
}

/* Write out a gcc function trailer.  */
static void
write_gcc_func_trailer(char *package, char *name, struct params *rets)
{
	if (rets == nil)
		;
	else if (rets->next == nil)
		bwritef(output, "return %s;\n", rets->name);
	else {
		struct params *p;

		bwritef(output, "  {\n    struct %s_%s_ret __ret;\n", package, name);
		for (p = rets; p != nil; p = p->next)
			bwritef(output, "    __ret.%s = %s;\n", p->name, p->name);
		bwritef(output, "    return __ret;\n  }\n");
	}
	bwritef(output, "}\n");
}

/* Write out a function header.  */
static void
write_func_header(char *package, char *name,
		  struct params *params, int paramwid,
		  struct params *rets)
{
	if (gcc)
		write_gcc_func_header(package, name, params, rets);
	else
		write_6g_func_header(package, name, params, paramwid, rets);
	bwritef(output, "#line %d \"%s\"\n", lineno, file);
}

/* Write out a function trailer.  */
static void
write_func_trailer(char *package, char *name,
		   struct params *rets)
{
	if (gcc)
		write_gcc_func_trailer(package, name, rets);
	else
		write_6g_func_trailer(rets);
}

/*
 * Read and write the body of the function, ending in an unnested }
 * (which is read but not written).
 */
static void
copy_body(void)
{
	int nesting = 0;
	while (1) {
		int c;

		c = getchar_no_eof();
		if (c == '}' && nesting == 0)
			return;
		xputchar(c);
		switch (c) {
		default:
			break;
		case '{':
			++nesting;
			break;
		case '}':
			--nesting;
			break;
		case '/':
			c = getchar_update_lineno();
			xputchar(c);
			if (c == '/') {
				do {
					c = getchar_no_eof();
					xputchar(c);
				} while (c != '\n');
			} else if (c == '*') {
				while (1) {
					c = getchar_no_eof();
					xputchar(c);
					if (c == '*') {
						do {
							c = getchar_no_eof();
							xputchar(c);
						} while (c == '*');
						if (c == '/')
							break;
					}
				}
			}
			break;
		case '"':
		case '\'':
			{
				int delim = c;
				do {
					c = getchar_no_eof();
					xputchar(c);
					if (c == '\\') {
						c = getchar_no_eof();
						xputchar(c);
						c = '\0';
					}
				} while (c != delim);
			}
			break;
		}
	}
}

/* Process the entire file.  */
static void
process_file(void)
{
	char *package, *name;
	struct params *params, *rets;
	int paramwid;

	package = read_package();
	read_preprocessor_lines();
	while (read_func_header(&name, &params, &paramwid, &rets)) {
		write_func_header(package, name, params, paramwid, rets);
		copy_body();
		write_func_trailer(package, name, rets);
		xfree(name);
		free_params(params);
		free_params(rets);
	}
	xfree(package);
}

void
goc2c(char *goc, char *c)
{
	Buf in, out;
	
	binit(&in);
	binit(&out);
	
	file = goc;
	readfile(&in, goc);

	// TODO: set gcc=1 when using gcc

	if(!gcc && streq(goarch, "amd64")) {
		type_table[Uintptr].size = 8;
		type_table[String].size = 16;
		type_table[Slice].size = 8+4+4;
		type_table[Eface].size = 8+8;
		structround = 8;
	}

	bprintf(&out, "// auto generated by go tool dist\n\n");
	input = bstr(&in);
	output = &out;

	process_file();
	
	writefile(&out, c);
}
