Example #1
0
static void codegen_prelude_input() {
	emit_comment("-> prelude function: input");
	pseudo_fun_head("input");
	emit_RO("IN", ax, ignore, ignore, "input ax");
	pseudo_return();
	emit_comment("<- prelude function: input");
}
Example #2
0
static void codegen_prelude_output() {
	emit_comment("-> prelude function: output");
	pseudo_fun_head("output");
	emit_RM("LD", ax, 2, bp, "ax = data[bp+2] (param 0)");
	emit_RO("OUT", ax, ignore, ignore, "output ax");
	pseudo_return();
	emit_comment("<- prelude function: output");
}
void SourceAssembler::comment_section(const char* format, ...) {
  emit("\n");
  emit_comment("----------------------------------------------------------");
  va_list arguments;
  va_start(arguments, format);
  emit_comment(format, arguments);
  va_end(arguments);
  emit_comment("----------------------------------------------------------");
}
Example #4
0
static void codegen_init(void) {
	int size = top_symtab()->size;

	emit_comment("-> init zero, gp, sp");
	pseudo_mov_const(zero, 0, "zero = 0 (noneed)");
	emit_RM("LD", gp, 0, zero, "gp = data[0] (maxaddress)");
	emit_RM("ST", zero, 0, zero, "data[0] = 0");
	pseudo_mov_reg(sp, gp, -size+1, "sp = gp - global_var_size + 1");
	emit_comment("<- init zero, gp, sp");
}
Example #5
0
void frarptbreak(void)
{
    /* If we're breaking out of current iteration, just neuter until ENDR */
    frarptskip = 1;
    frarptcnt  = 0;
    emit_comment(0, "  Break Taken");
}
Example #6
0
bool FTEST_dirname(void) {
	emit_function("function:  condor_dirname(const char *path)");
	emit_comment("comment: A dirname() function that is happy on both Unix and NT. This allocates space for a new string that holds the path of the parent directory of the path it was given.  If the given path has no directory delimiters, or is NULL, we just return '.'.  In all cases, the string we return is new space, and must be deallocated with free().   Derek Wright 9/23/99");
	FunctionDriver driver;
	driver.register_function(test_null);
	driver.register_function(test_empty_string);
	driver.register_function(test_current_directory);
	driver.register_function(test_simple_path_1);
	driver.register_function(test_simple_path_2);
	driver.register_function(test_simple_directory_1);
	driver.register_function(test_simple_directory_2);
	driver.register_function(test_directory_and_file_1);
	driver.register_function(test_directory_and_file_2);
	driver.register_function(test_root_directory);
	driver.register_function(test_directory_and_directory);
	driver.register_function(test_directory_and_directory_in_root);
	driver.register_function(test_forward_slash);
	driver.register_function(test_backslash);
	driver.register_function(test_period_and_forward_slash_1);
	driver.register_function(test_period_and_backslash_1);
	driver.register_function(test_period_and_forward_slash_2);
	driver.register_function(test_period_and_backslash_2);
	driver.register_function(test_backslash_and_period);
	driver.register_function(test_forward_slash_and_file_extension);
	driver.register_function(test_backslash_and_file_extension);
	driver.register_function(test_period_and_forward_slash);
	driver.register_function(test_period_and_backslash);
	driver.register_function(test_period_and_forward_slash_with_special_file);
	driver.register_function(test_period_and_backslash_with_special_file);
	driver.register_function(test_double_forward_slash);
	driver.register_function(test_double_backslash);
	return driver.do_all_functions();
}
void SourceAssembler::define_struct_begin(const char* struct_type_name, 
                                          const char* struct_name) {
  emit_comment("Definition of %s", struct_name);
  if (GenerateInlineAsm) {
    emit("struct %s {\n", struct_type_name);
  } else {
    entry(struct_name);
  }
}
Example #8
0
bool FTEST_strlwr(void) {
	emit_function("char* strlwr(char* src)");
	emit_comment("Convert a string, in place, to the lowercase version of it.");
	emit_problem("Function does no error checking on the size of string");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
	driver.register_function(test_normal_case);
	driver.register_function(test_return_value);
	
		// run the tests
	return driver.do_all_functions();
}
Example #9
0
void codegen_root(Ast root) {
	emit_comment("-> beginning of TM code");

	codegen_init();
	
	// jmp to main 改成 call main 后面跟 HALT
	emit_comment("skip 5: call main, waiting for addr of main()");
	int call_main_loc = emit_skip(5);
	emit_RO("HALT", ignore, ignore, ignore, "stop program");

	codegen_prelude_input();
	codegen_prelude_output();

	codegen_stmt(root);

	// backpatch add of main
	emit_backup(call_main_loc);
	pseudo_call(lookup_funinfo("main"));
	emit_restore();

	emit_comment("<- end of TM code");
}
void SourceAssembler::define_call_info() {
#if ENABLE_EMBEDDED_CALLINFO
  // Only the interpreter defined call info in the source assembler
  CallInfo ci = CallInfo::interpreter();
  emit_comment("call info");
  if (!GenerateGNUCode)
    if (!GenerateInlineAsm)
      emit("\ttest eax, %d\n", ci.raw());
    else
      emit("\t__asm test eax, %d\n", ci.raw());
  else
    emit("\ttest $%d, %%eax\n", ci.raw());
#endif // ENABLE_EMBEDDED_CALLINFO
}
bool FTEST_is_valid_sinful(void) {
		// beginning junk for getPortFromAddr(() {
	emit_function("int is_valid_sinful(char* sinful)");
	emit_comment("Determines if a function is a valid sinful string.");
	emit_problem("None");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
	driver.register_function(test_normal_case);
	driver.register_function(test_hostname);
	driver.register_function(test_no_angle_brackets);
	
		// run the tests
	return driver.do_all_functions();
}
Example #12
0
bool FTEST_tokener(void) {
		// beginning junk for getPortFromAddr(() {
	emit_function("tokener class and SORTED/UNSORTED_TOKENER_TABLE");
	emit_comment("tokenizing and efficient lookup by name in a static const table");

		// driver to run the tests and all required setup
	FunctionDriver driver;
	driver.register_function(test_unsorted_table);
	driver.register_function(test_sorted_table);
	driver.register_function(test_nocase_sorted_table);
	driver.register_function(test_tokener_parse_basic);
	driver.register_function(test_tokener_parse_regex);
	driver.register_function(test_tokener_parse_realistic);

		// run the tests
	return driver.do_all_functions();
}
Example #13
0
bool FTEST_fullpath(void) {
	emit_function("int fullpath( const char* path )");
	emit_comment("return TRUE if the given path is a full pathname, FALSE if not.  by full pathname, we mean it either begins with '/' or '\' or '*:\' (something like 'c:\\...' on windoze).");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
	driver.register_function(test_forward_slash);
	driver.register_function(test_name);
	driver.register_function(test_drive_path_backslash);
	driver.register_function(test_colon_backslash);
	driver.register_function(test_backslash);
	driver.register_function(test_drive_path_forward_slash);
	driver.register_function(test_colon_forward_slash);
	
		// run the tests
	return driver.do_all_functions();
}
bool FTEST_string_to_sin(void) {
		// beginning junk for getPortFromAddr(() {
	emit_function("string_to_sin(const char*, struct sockaddr_in*)");
	emit_comment("Converts a sinful string to a sockaddr_in.");
	emit_problem("Port numbers must be passed through htons as expected, but IP addresses should not be passed through htonl.");
	emit_problem("Function assumes a well-formatted string if it sees a : anywhere.");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
#ifdef IPV6_REMOVED
	driver.register_function(test_normal_case);
	driver.register_function(test_alpha_input);
#endif
	
		// run the tests
	return driver.do_all_functions();
}
bool FTEST_is_valid_network(void) {
		// beginning junk for getPortFromAddr(() {
	emit_function("int is_valid_network(char* network, struct in_addr* ip, struct in_addr* mask)");
	emit_comment("Returns true if the given string is a valid network.");
	emit_problem("Allows the use of wildcards in addresses and netmasks.");
	emit_problem("Doesn't check to see if the netmask is a valid netmask, if it sees something like an IP address it assumes everything works.");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
#ifdef IPV6_REMOVED
	driver.register_function(test_normal_case);
	driver.register_function(test_slash_notation);
	driver.register_function(test_classless_mask);
	driver.register_function(test_wildcard);
	driver.register_function(test_plain_ip);
#endif
	
		// run the tests
	return driver.do_all_functions();
}
Example #16
0
bool FTEST_is_ipaddr(void) {
		// beginning junk for getPortFromAddr(() {
	emit_function("int is_ipaddr(char* addr)");
	emit_comment("Determines if a function is an ip address (with wildcards allowed).");
	emit_problem("None");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
#ifdef IPV6_REMOVED
	driver.register_function(test_normal_case);
	driver.register_function(test_one_octet_wildcard);
	driver.register_function(test_upper_bound);
	driver.register_function(test_lower_bound);
	driver.register_function(test_only_wildcard);
	driver.register_function(test_start_wildcard);
#endif
	
		// run the tests
	return driver.do_all_functions();
}
Example #17
0
void frarptendr()   /* begin actually looping repeat block */
{
    if (frarptact <= 0)
    {
        fraerror("Unexpected ENDR");
        return;
    }

    /* Count down the repeat block, and increment our interation number */
    frarptcnt--;
    frarptnum++;

    /* Output what the current loop iteration number is  */
    emit_comment(0, "  ;== %d", frarptnum);

    /* If loop expires, pop to previous level.  Otherwise, rewind curr to   */
    /* head of current repeat loop.                                         */
    if (frarptcnt < 0)  frarptpop();
    else                rpt_curr = rpt[frarptact - 1].head;
}
Example #18
0
bool FTEST_sin_to_string(void) {
	const char* h = "<[fe80::862b:2bff:fe98:65f2]:9618>";
	condor_sockaddr addr;
	addr.from_sinful(h);


		// beginning junk for getPortFromAddr(() {
	emit_function("sin_to_string(sockaddr_in)");
	emit_comment("Converts a sockaddr_in to a sinful string.");
	emit_problem("None");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
#ifdef IPV6_REMOVED
	driver.register_function(test_normal_case);
#endif
	
		// run the tests
	return driver.do_all_functions();
}
Example #19
0
bool FTEST_stl_string_utils(void) {
		// beginning junk for getPortFromAddr(() {
	emit_function("STL string utils");
	emit_comment("Package of functions/operators to facilitate adoption of std::string");
	
		// driver to run the tests and all required setup
	FunctionDriver driver;
	driver.register_function(test_comparison_ops_lhs_string);
	driver.register_function(test_comparison_ops_lhs_MyString);
	driver.register_function(test_sprintf_string);
	driver.register_function(test_sprintf_MyString);
	driver.register_function(test_sprintf_cat_string);
	driver.register_function(test_sprintf_cat_MyString);
	driver.register_function(test_lower_case_empty);
	driver.register_function(test_lower_case_non_empty);
	driver.register_function(test_upper_case_empty);
	driver.register_function(test_upper_case_non_empty);
	driver.register_function(test_chomp_new_line_end);
	driver.register_function(test_chomp_crlf_end);
	driver.register_function(test_chomp_new_line_beginning);
	driver.register_function(test_chomp_return_false);
	driver.register_function(test_chomp_return_true);
	driver.register_function(test_trim_beginning_and_end);
	driver.register_function(test_trim_end);
	driver.register_function(test_trim_none);
	driver.register_function(test_trim_beginning);
	driver.register_function(test_trim_empty);
	driver.register_function(tokenize_null);
	driver.register_function(tokenize_skip);
	driver.register_function(tokenize_multiple_calls);
	driver.register_function(tokenize_end);
	driver.register_function(tokenize_empty);
	driver.register_function(tokenize_empty_delimiter);
	
		// run the tests
	return driver.do_all_functions();
}
Example #20
0
// return: ax
static void codegen_exp(Ast node) {
	assert(node != NULL);

	switch(node->kind) {

	case Decl_Var:
	case Decl_Param:
	case Decl_Fun:
		error(Bug, "declaration ast node should not attend in codegen_exp()");

	case Stat_Compound:
	case Stat_Select:
	case Stat_Iterate:
	case Stat_Return:
	case Stat_Empty:
	case Stat_Expression:
		error(Bug, "statement ast node should not attend in codegen_exp()");

	case Expr_Assign:
		emit_comment("-> assign");

		donot_fetch_var_value = TRUE;
		codegen_exp(node->children[0]);
		pseudo_push(ax, "push ax");
		donot_fetch_var_value = FALSE;
		
		codegen_exp(node->children[1]);
		
		pseudo_pop(bx, "pop bx");
		emit_RM("ST", ax, 0, bx, "data[bx] = ax");
		
		emit_comment("<- assign");
		break;

	case Expr_Binary:
		emit_comment("-> op");
		
		codegen_exp(node->children[0]); // left sub-exp
		pseudo_push(ax, "push ax");
		codegen_exp(node->children[1]); // right sub-exp
		pseudo_pop(bx, "push bx");
		
		switch(node->operator) {
			case '+': emit_RO("ADD", ax, bx, ax, "ax = bx + ax"); break;
			case '-': emit_RO("SUB", ax, bx, ax, "ax = bx - ax"); break;
			case '*': emit_RO("MUL", ax, bx, ax, "ax = bx * ax"); break;
			case '/': emit_RO("DIV", ax, bx, ax, "ax = bx / ax"); break;
			case EQ: pseudo_compare("JEQ"); break;
			case NE: pseudo_compare("JNE"); break;
			case LT: pseudo_compare("JLT"); break;
			case LE: pseudo_compare("JLE"); break;
			case GT: pseudo_compare("JGT"); break;
			case GE: pseudo_compare("JGE"); break;
			default:
				error(Bug, "unknown operator");
		}
		
		emit_comment("<- op");
		break;

	case Expr_Fun:
		emit_comment("-> call function:");
		emit_comment(node->name);
		
		FunInfo funinfo = lookup_funinfo(node->name);
		Entry entry = funinfo->symtab->head;
		Ast param = node->children[0];

		while(entry != NULL && param != NULL) { // parameter order: form right to left
			if(entry->type == IntArrayT && param->kind == Expr_Var) { // special case (very restricted)
				donot_fetch_var_value = TRUE;
			}
			codegen_exp(param);
			pseudo_push(ax, "push ax (parameter)");
			donot_fetch_var_value = FALSE;

			entry = entry->next;
			param = param->sibling; // list of expression, only here
		}
		
		pseudo_call(funinfo);
		emit_comment("<- call function");
		break;

	case Expr_Var:
		emit_comment("-> var");
		pseudo_get_var_addr(node);
		if(node->type == IntArrayT) {
			pseudo_push(ax, "push ax");

			saved_config = donot_fetch_var_value;
			donot_fetch_var_value = FALSE;
			codegen_exp(node->children[0]);
			donot_fetch_var_value = saved_config;

			pseudo_pop(bx, "pop bx");
			emit_RO("SUB", ax, bx, ax, "ax = bx - ax (array offset)");
		} else {
			assert(node->type == IntT);
		}
		if(! donot_fetch_var_value) {
			emit_RM("LD", ax, 0, ax, "ax = data[ax]");
		}
		emit_comment("<- var");
		break;

	case Expr_Const:
		emit_comment("-> const");
		pseudo_mov_const(ax, node->number, "ax = const value");
		emit_comment("-> const");
		break;

	default:
		error(Bug, "unknown ast node kind");
	}
}
void SourceAssembler::start() {
  _current_segment = NO_SEGMENT;

  // Emit the header.
  emit_comment("Copyright  1990-2009 Sun Microsystems, Inc. All Rights Reserved.");
  emit_comment("DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER");
  emit_comment("");
  emit_comment("This program is free software; you can redistribute it and/or");
  emit_comment("modify it under the terms of the GNU General Public License version");
  emit_comment("2 only, as published by the Free Software Foundation.");
  emit_comment("");
  emit_comment("This program is distributed in the hope that it will be useful, but");
  emit_comment("WITHOUT ANY WARRANTY; without even the implied warranty of");
  emit_comment("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
  emit_comment("General Public License version 2 for more details (a copy is");
  emit_comment("included at /legal/license.txt).");
  emit_comment("");
  emit_comment("You should have received a copy of the GNU General Public License");
  emit_comment("version 2 along with this work; if not, write to the Free Software");
  emit_comment("Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA");
  emit_comment("02110-1301 USA");
  emit_comment("");
  emit_comment("Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa");
  emit_comment("Clara, CA 95054 or visit www.sun.com if you need additional");
  emit_comment("information or have any questions.");
  emit("\n");

  if (GenerateInlineAsm) {
      if (1) {                  // visual c++
          emit("#define __DECLSPEC_ALIGN(x)\n");
      } else {
          emit("#define __DECLSPEC_ALIGN(x) __declspec(align(x))\n");
      }
  }
  // Make sure people know that this file shouldn't be edited.
  comment_section("Generated assembly file -- do *not* edit");
  emit("\n");
 
  // Emit the platform and model specifiers.
  if (!GenerateGNUCode) {
    if (!GenerateInlineAsm) {
      emit("\t.486P\n");
      emit("\t.MODEL flat, C\n\n");
    }
  } else {
    emit("\t.arch i486\n");
  }
  start_code_segment();
}
void SourceAssembler::define_struct_end(const char* struct_name) {
  if (GenerateInlineAsm) {
    emit("} %s;\n", struct_name);
  }
  emit_comment("End definition of struct %s", struct_name);
}
Example #23
0
File: emit_c.c Project: tbeu/lcm
/** Emit header file output specific to a particular type of struct. **/
static void emit_header_struct(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *tn_upper = g_utf8_strup(tn_, -1);

    // include header files required by members
    for (unsigned int i = 0; i < g_ptr_array_size(ls->members); i++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, i);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
             strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_underscores (lm->type->lctypename);
            fprintf(f, "#include \"%s%s%s.h\"\n",
                    getopt_get_string(lcm->gopt, "cinclude"),
                    strlen(getopt_get_string(lcm->gopt, "cinclude"))>0 ? "/" : "",
                    other_tn);
            free (other_tn);
        }
    }

    // output constants
    for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
        lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
        assert(lcm_is_legal_const_type(lc->lctypename));
        const char *suffix = "";
        if (!strcmp(lc->lctypename, "int64_t")) {
            suffix = "LL";
        }
        emit_comment(f, 0, lc->comment);
        emit(0, "#define %s_%s %s%s", tn_upper, lc->membername, lc->val_str,
                suffix);
    }
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(0, "");
    }

    // define the struct
    emit_comment(f, 0, ls->comment);
    emit(0, "typedef struct _%s %s;", tn_, tn_);
    emit(0, "struct _%s", tn_);
    emit(0, "{");

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        emit_comment(f, 1, lm->comment);

        int ndim = g_ptr_array_size(lm->dimensions);
        if (ndim == 0) {
            emit(1, "%-10s %s;", map_type_name(lm->type->lctypename),
                    lm->membername);
        } else {
            if (lcm_is_constant_size_array(lm)) {
                emit_start(1, "%-10s %s", map_type_name(lm->type->lctypename), lm->membername);
                for (unsigned int d = 0; d < ndim; d++) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                    emit_continue("[%s]", ld->size);
                }
                emit_end(";");
            } else {
                emit_start(1, "%-10s ", map_type_name(lm->type->lctypename));
                for (unsigned int d = 0; d < ndim; d++)
                    emit_continue("*");
                emit_end("%s;", lm->membername);
            }
        }
    }
    emit(0, "};");
    emit(0, "");

    free(tn_);
    g_free(tn_upper);
}
Example #24
0
/** Emit header file **/
static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *sn = ls->structname->shortname;
    char *tn_ = dots_to_underscores(tn);

    emit_auto_generated_warning(f);

    fprintf(f, "#include <lcm/lcm_coretypes.h>\n");
    fprintf(f, "\n");
    fprintf(f, "#ifndef __%s_hpp__\n", tn_);
    fprintf(f, "#define __%s_hpp__\n", tn_);
    fprintf(f, "\n");

    // do we need to #include <vector> ?
    int emit_include_vector = 0;
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *)g_ptr_array_index(ls->members, mind);
        if (g_ptr_array_size(lm->dimensions) != 0 &&
                !lcm_is_constant_size_array(lm) && !emit_include_vector) {
            emit(0, "#include <vector>");
            emit_include_vector = 1;
        }
    }

    emit(0, "#include <cmath>\t// For fabs to compare floats");
    emit(0, "#include <string>\t// For return type of toStr()");
    emit(0, "#include <sstream>\t// For stringstream in toStr()");

    // include header files for other LCM types
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
                strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_slashes (lm->type->lctypename);
            emit(0, "#include \"%s%s%s.hpp\"",
                 getopt_get_string(lcmgen->gopt, "cpp-include"),
                 strlen(getopt_get_string(lcmgen->gopt, "cpp-include"))>0 ? G_DIR_SEPARATOR_S : "",
                 other_tn);
            free(other_tn);
        }
    }

    fprintf(f, "\n");
    emit_package_namespace_start(lcmgen, f, ls);

    // define the class
    emit(0, "");
    emit_comment(f, 0, ls->comment);
    emit(0, "class %s", sn);
    emit(0, "{");

    // data members
    if(g_ptr_array_size(ls->members)) {
        emit(1, "public:");
        for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

            emit_comment(f, 2, lm->comment);
            char const* mapped_typename = map_type_name(lm->type->lctypename);
            int ndim = g_ptr_array_size(lm->dimensions);
            if (ndim == 0) {
                emit(2, "%-10s %s;", mapped_typename, lm->membername);
            } else {
                if (lcm_is_constant_size_array(lm)) {
                    emit_start(2, "%-10s %s", mapped_typename, lm->membername);
                    for (unsigned int d = 0; d < ndim; d++) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                        emit_continue("[%s]", ld->size);
                    }
                    emit_end(";");
                } else {
                    emit_start(2, "");
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue("std::vector< ");
                    emit_continue("%s", mapped_typename);
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue(" >");
                    emit_end(" %s;", lm->membername);
                }
            }
            if (mind < g_ptr_array_size(ls->members) - 1) {
                emit(0, "");
            }
        }
        emit(0, "");
    }

    // constants
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(1, "public:");
        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
            assert(lcm_is_legal_const_type(lc->lctypename));

            emit_comment(f, 2, lc->comment);
            // For int32_t only, we emit enums instead of static const
            // values because the former can be passed by reference while
            // the latter cannot.
            if (!strcmp(lc->lctypename, "int32_t")) {
                emit(2, "enum { %s = %s };", lc->membername, lc->val_str);
            } else {
                const char *suffix = "";
                if (!strcmp(lc->lctypename, "int64_t"))
                    suffix = "LL";
                char const* mapped_typename = map_type_name(lc->lctypename);
                char *cpp_std = getopt_get_string(lcmgen->gopt, "cpp-std");
                if(strcmp("c++98",cpp_std) && strcmp("c++11",cpp_std)) {
                    printf("%s is not a valid cpp_std. Use --cpp-std=c++98 or --cpp-std=c++11 instead\n\n", cpp_std);
                    fflush(stdout);
                    _exit(1);
                }

                if(!strcmp (cpp_std, "c++11")) {
                    emit(2, "static constexpr %-8s %s = %s%s;", mapped_typename,
                         lc->membername, lc->val_str, suffix);
                } else {
                    emit(2, "// If you're using C++11 and are getting compiler errors saying things like");
                    emit(2, "// ‘constexpr’ needed for in-class initialization of static data member");
                    emit(2, "// then re-run lcm-gen with '--cpp-std=c++11' to generate code that is");
                    emit(2, "// compliant with C++11");
                    emit(2, "static const %-8s %s = %s%s;", mapped_typename,
                         lc->membername, lc->val_str, suffix);
                }
            }
        }
        emit(0, "");
    }

    emit(1, "public:");
    emit(2, "/**");
    emit(2, " * Encode a message into binary form.");
    emit(2, " *");
    emit(2, " * @param buf The output buffer.");
    emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
    emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
    emit(2, " *  equal to getEncodedSize().");
    emit(2, " * @return The number of bytes encoded, or <0 on error.");
    emit(2, " */");
    emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Check how many bytes are required to encode this message.");
    emit(2, " */");
    emit(2, "inline int getEncodedSize() const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Decode a message from binary form into this instance.");
    emit(2, " *");
    emit(2, " * @param buf The buffer containing the encoded message.");
    emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
    emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(2, " */");
    emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Compare two instances of the same type.");
    emit(2, " *");
    emit(2, " * @param[in] other The object to compare.");
    emit(2, " * @return true if all elements are equal, false otherwise.");
    emit(2, " */");
    emit(2, "inline bool operator==(%s const & other) const;", sn);
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Construct a string from the object for debugging purposes.");
    emit(2, " * Note that arrays are cropped for readability. Only the first and last elements are shown.");
    emit(2, " *");
    emit(2, " * @param[in] layout A placeholder for the tree structure.");
    emit(2, " */");
    emit(2, "inline std::string toDebugStr(std::string const & layout=\"|-\") const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Initialize all values of a test object to pre-defined values.");
    emit(2, " * The values used are much more informative than using 0 because");
    emit(2, " * they are type-dependant. This way, the user knows directly whether");
    emit(2, " * the type is correct or not. Typically the default values are the");
    emit(2, " * maximum value allowed by the type minus 5, and 1.0 for float and double.");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @return success.");
    emit(2, " */");
    emit(2, "inline bool initTestObject();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Increment every variable in the object.");
    emit(2, " * Works well with initTestObject() and compareTestObject().");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @return success.");
    emit(2, " */");
    emit(2, "inline bool incTestObject();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Compare two instances of the same type.");
    emit(2, " * Works well with initTestObject() and incTestObject().");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @param[in] other The object to compare.");
    emit(2, " * @return true if all elements are equal, false otherwise.");
    emit(2, " */");
    emit(2, "inline bool compareTestObject(%s const & other) const;", sn);
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
    emit(2, " * Note that the fingerprint is the same for all instances of the same");
    emit(2, " * message type, and is a fingerprint on the message type definition, not on");
    emit(2, " * the message contents.");
    emit(2, " */");
    emit(2, "inline static int64_t getHash();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Returns \"%s\"", ls->structname->shortname);
    emit(2, " */");
    emit(2, "inline static const char* getTypeName();");

    emit(0, "");
    emit(2, "// LCM support functions. Users should not call these");
    emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
    emit(2, "inline int _getEncodedSizeNoHash() const;");
    emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
    emit(2, "inline static uint64_t _computeHash(const __lcm_hash_ptr *p);");
    emit(0, "};");
    emit(0, "");

    free(tn_);
}
Example #25
0
static void codegen_stmt(Ast node) {
	int saved_loc_1 = -1;
	int saved_loc_2 = -1;
	int current_loc = -1;

	while(node != NULL) {
		switch(node->kind) {

		case Decl_Var: // skip
			break;

		case Decl_Param: // skip
			break;

		case Decl_Fun:
			push_symtab(node->symtab);
			emit_comment("-> function:");
			emit_comment(node->name);

			pseudo_fun_head(node->name);
			codegen_stmt(node->children[1]); // recursion: function body
			pseudo_return();

			emit_comment("<- function");
			pop_symtab();
			break;

		case Stat_Compound:
			push_symtab(node->symtab);
			emit_comment("-> compound");
			codegen_stmt(node->children[0]); // recursion
			emit_comment("<- compound");
			pop_symtab();
			break;

		case Stat_Select:
			emit_comment("-> if");
			
			codegen_exp(node->children[0]); // value in ax

			saved_loc_1 = emit_skip(1);
			emit_comment("skip: conditional jmp to else");
			
			codegen_stmt(node->children[1]); // recursion
			
			saved_loc_2 = emit_skip(1);
			emit_comment("skip: unconditional jmp to end");
			
			current_loc = emit_skip(0);
			emit_backup(saved_loc_1);
			emit_RM("JEQ", ax, current_loc, zero, "if ax == 0, pc = addr of else");
			emit_restore();
			
			codegen_stmt(node->children[2]); // recursion
			
			current_loc = emit_skip(0);
			emit_backup(saved_loc_2);
			pseudo_mov_const(pc, current_loc, "pc = addr of endif");
			emit_restore();
			emit_comment("<- if");
			break;

		case Stat_Iterate:
			emit_comment("-> while");
			
			saved_loc_1 = emit_skip(0);
			
			codegen_exp(node->children[0]);
			
			saved_loc_2 = emit_skip(1);
			emit_comment("skip: conditional jmp to end");
			
			codegen_stmt(node->children[1]); // recursion
			
			pseudo_mov_const(pc, saved_loc_1, "pc = addr of while");
			
			current_loc = emit_skip(0);
			emit_backup(saved_loc_2);
			emit_RM("JEQ", ax, current_loc, zero, "if ax == 0, pc = add of endwhile");
			emit_restore();
			
			emit_comment("<- while");
			break;

		case Stat_Return:
			emit_comment("-> return");
			if(node->type == IntT) {
				codegen_exp(node->children[0]); // return value now in ax
			} else {
				assert(node->type == VoidT);
			}
			pseudo_return();
			emit_comment("<- return");
			break;

		case Stat_Empty: // skip
			break;

		case Stat_Expression:
			emit_comment("-> expression statement");
			codegen_exp(node->children[0]);
			emit_comment("<- expression statement");
			break;

		case Expr_Assign:
		case Expr_Binary:
		case Expr_Fun:
		case Expr_Var:
		case Expr_Const:
			error(Bug, "expression ast node should not attend in codegen_stmt()");

		default:
			error(Bug, "unknown ast node kind");
		}

		node = node->sibling;
	}
}
Example #26
0
File: emit_cpp.c Project: ahans/lcm
/** Emit header file **/
static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *sn = ls->structname->shortname;
    char *tn_ = dots_to_underscores(tn);

    emit_auto_generated_warning(f);

    fprintf(f, "#include <lcm/lcm_coretypes.h>\n");
    fprintf(f, "\n");
    fprintf(f, "#ifndef __%s_hpp__\n", tn_);
    fprintf(f, "#define __%s_hpp__\n", tn_);
    fprintf(f, "\n");

    // do we need to #include <vector> and/or <string>?
    int emit_include_vector = 0;
    int emit_include_string = 0;
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *)g_ptr_array_index(ls->members, mind);
        if (g_ptr_array_size(lm->dimensions) != 0 &&
            !lcm_is_constant_size_array(lm) && !emit_include_vector) {
            emit(0, "#include <vector>");
            emit_include_vector = 1;
        }
        if(!emit_include_string &&
            !strcmp(lm->type->lctypename, "string")) {
            emit(0, "#include <string>");
            emit_include_string = 1;
        }
    }

    // include header files for other LCM types
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_slashes (lm->type->lctypename);
            emit(0, "#include \"%s%s%s.hpp\"",
                    getopt_get_string(lcmgen->gopt, "cpp-include"),
                    strlen(getopt_get_string(lcmgen->gopt, "cpp-include"))>0 ? G_DIR_SEPARATOR_S : "",
                    other_tn);
            free(other_tn);
        }
    }

    fprintf(f, "\n");
    emit_package_namespace_start(lcmgen, f, ls);

    // define the class
    emit(0, "");
    emit_comment(f, 0, ls->comment);
    emit(0, "class %s", sn);
    emit(0, "{");

    // data members
    if(g_ptr_array_size(ls->members)) {
        emit(1, "public:");
        for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

            emit_comment(f, 2, lm->comment);
            char* mapped_typename = map_type_name(lm->type->lctypename);
            int ndim = g_ptr_array_size(lm->dimensions);
            if (ndim == 0) {
                emit(2, "%-10s %s;", mapped_typename, lm->membername);
            } else {
                if (lcm_is_constant_size_array(lm)) {
                    emit_start(2, "%-10s %s", mapped_typename, lm->membername);
                    for (unsigned int d = 0; d < ndim; d++) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                        emit_continue("[%s]", ld->size);
                    }
                    emit_end(";");
                } else {
                    emit_start(2, "");
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue("std::vector< ");
                    emit_continue("%s", mapped_typename);
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue(" >");
                    emit_end(" %s;", lm->membername);
                }
            }
            free(mapped_typename);
            if (mind < g_ptr_array_size(ls->members) - 1) {
                emit(0, "");
            }
        }
        emit(0, "");
    }

    // constants
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(1, "public:");
        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
            assert(lcm_is_legal_const_type(lc->lctypename));

            emit_comment(f, 2, lc->comment);
            // For int32_t only, we emit enums instead of static const
            // values because the former can be passed by reference while
            // the latter cannot.
            if (!strcmp(lc->lctypename, "int32_t")) {
              emit(2, "enum { %s = %s };", lc->membername, lc->val_str);
            } else {
              const char *suffix = "";
              if (!strcmp(lc->lctypename, "int64_t"))
                suffix = "LL";
              char* mapped_typename = map_type_name(lc->lctypename);
              emit(2, "static const %-8s %s = %s%s;", mapped_typename,
                  lc->membername, lc->val_str, suffix);
              free(mapped_typename);
            }
        }
        emit(0, "");
    }

    emit(1, "public:");
    emit(2, "/**");
    emit(2, " * Encode a message into binary form.");
    emit(2, " *");
    emit(2, " * @param buf The output buffer.");
    emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
    emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
    emit(2, " *  equal to getEncodedSize().");
    emit(2, " * @return The number of bytes encoded, or <0 on error.");
    emit(2, " */");
    emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Check how many bytes are required to encode this message.");
    emit(2, " */");
    emit(2, "inline int getEncodedSize() const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Decode a message from binary form into this instance.");
    emit(2, " *");
    emit(2, " * @param buf The buffer containing the encoded message.");
    emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
    emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(2, " */");
    emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
    emit(2, " * Note that the fingerprint is the same for all instances of the same");
    emit(2, " * message type, and is a fingerprint on the message type definition, not on");
    emit(2, " * the message contents.");
    emit(2, " */");
    emit(2, "inline static int64_t getHash();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Returns \"%s\"", ls->structname->shortname);
    emit(2, " */");
    emit(2, "inline static const char* getTypeName();");

    emit(0, "");
    emit(2, "// LCM support functions. Users should not call these");
    emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
    emit(2, "inline int _getEncodedSizeNoHash() const;");
    emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
    emit(2, "inline static int64_t _computeHash(const __lcm_hash_ptr *p);");
    emit(0, "};");
    emit(0, "");

    free(tn_);
}