Example #1
0
/**
 * CTRParserReference
 *
 * Generates the nodes to respresent a variable or property.
 */
ctr_tnode* ctr_cparse_ref() {
	ctr_tnode* r;
	char* tmp;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_REFERENCE;
	r->vlen = ctr_clex_tok_value_length();
	tmp = ctr_clex_tok_value();
	if (strncmp("my", tmp, 2)==0 && r->vlen == 2) {
		int t = ctr_clex_tok();
		if (t != CTR_TOKEN_REF) {
			printf("'My' should always be followed by property name!\n");
			exit(1);
		}
		tmp = ctr_clex_tok_value();
		r->modifier = 1;
		r->vlen = ctr_clex_tok_value_length();
	}
	if (strncmp("var", tmp, 3)==0 && r->vlen == 3) {
		int t = ctr_clex_tok();
		if (t != CTR_TOKEN_REF) {
			printf("'var' should always be followed by property name!\n");
			exit(1);
		}
		tmp = ctr_clex_tok_value();
		r->modifier = 2;
		r->vlen = ctr_clex_tok_value_length();
	}
	r->value = ctr_malloc(r->vlen, 0);
	memcpy(r->value, tmp, r->vlen);
	return r;
}
Example #2
0
/**
 * CTRParserFin
 *
 * Generates a node to represent the end of a program.
 */
ctr_tnode* ctr_cparse_fin() {
	ctr_tnode* f;
	ctr_clex_tok();
	f = CTR_PARSER_CREATE_NODE();
	f->type = CTR_AST_NODE_ENDOFPROGRAM;
	return f;
}
Example #3
0
/**
 * CTRParserExpression
 *
 * Generates a set of nodes to represent an expression.
 */
ctr_tnode* ctr_cparse_expr(int mode) {
	ctr_tnode* r;
	ctr_tnode* e;
	int t2;
	ctr_tlistitem* nodes;
	ctr_tlistitem* rli;
	if (ctr_mode_debug) printf("Parsing expression (mode: %d).\n", mode);	
	r = ctr_cparse_receiver();
	t2 = ctr_clex_tok();
	if (ctr_mode_debug) printf("First token after receiver = %d \n", t2);
	ctr_clex_putback();
	if (r->type == CTR_AST_NODE_REFERENCE && t2 == CTR_TOKEN_ASSIGNMENT) {
		e = ctr_cparse_assignment(r);
	} else if (t2 != CTR_TOKEN_DOT && t2 != CTR_TOKEN_PARCLOSE && t2 != CTR_TOKEN_CHAIN) {
		e = CTR_PARSER_CREATE_NODE();
		e->type = CTR_AST_NODE_EXPRMESSAGE;
		nodes = ctr_cparse_messages(r, mode);
		if (nodes == NULL) {
			int t = ctr_clex_tok();
			ctr_clex_putback();
			if (ctr_mode_debug) printf("No messages, return. Next token: %d.\n", t);
			return r; /* no messages, then just return receiver (might be in case of argument). */
		}
		rli = CTR_PARSER_CREATE_LISTITEM();
		rli->node = r;
		rli->next = nodes;
		e->nodes = rli;
	} else {
		if (ctr_mode_debug) printf("Returning receiver. \n");
		return r;
	}
	return e;
}
Example #4
0
/**
 * CTRParserNil
 *
 * Generates a node to represent Nil
 */
ctr_tnode* ctr_cparse_nil() {
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRNIL;
	r->value = "Nil";
	r->vlen = 3;
	return r;
}
Example #5
0
/**
 * CTRParserBooleanTrue
 *
 * Generates a node to represent a boolean True.
 */
ctr_tnode* ctr_cparse_true() {
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRBOOLTRUE;
	ASSIGN_STRING(r, value,"True",4);	
	r->vlen = 4;
	return r;
}
Example #6
0
/**
 * CTRParserBooleanFalse
 *
 * Generates a node to represent a boolean False.
 */
ctr_tnode* ctr_cparse_false() {
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRBOOLFALSE;
	ASSIGN_STRING(r, value, "False", 5);
	r->vlen = 5;
	return r;
}
Example #7
0
/**
 * CTRParserAssignment
 *
 * Generates a node to represent an assignment.
 */
ctr_tnode* ctr_cparse_assignment(ctr_tnode* r) {
	ctr_tnode* a;
	ctr_tnode* assignmentExpr;
	ctr_tlistitem* li;
	ctr_tlistitem* liAssignExpr;
	ctr_clex_tok();
	a = CTR_PARSER_CREATE_NODE();
	assignmentExpr = CTR_PARSER_CREATE_NODE();
	li = CTR_PARSER_CREATE_LISTITEM();
	liAssignExpr = CTR_PARSER_CREATE_LISTITEM();
	a->type = CTR_AST_NODE_EXPRASSIGNMENT;
	a->nodes = li;
	li->node = r;
	assignmentExpr = ctr_cparse_expr(0);
	liAssignExpr->node = assignmentExpr;
	li->next = liAssignExpr;
	return a;
}
Example #8
0
/**
 * CTRParserReturn
 *
 * Generates a node to represent a return from a block of code.
 */
ctr_tnode* ctr_cparse_ret() {
	ctr_tlistitem* li;
	ctr_tnode* r;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_RETURNFROMBLOCK;
	li = CTR_PARSER_CREATE_LISTITEM();
	r->nodes = li;
	li->node = ctr_cparse_expr(0);
	return r;
}
Example #9
0
ctr_tnode* ctr_cparse_number() {
	char* n;
	ctr_tnode* r;
	long l;
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRNUM;
	n = ctr_clex_tok_value();
	l = ctr_clex_tok_value_length();
	r->value = ctr_malloc(sizeof(char) * l, 0);
	memcpy(r->value, n, l);
	r->vlen = l;
	return r;
}
Example #10
0
/**
 * CTRParserString
 *
 * Generates a node to represent a string.
 */
ctr_tnode* ctr_cparse_string() {
	ctr_tnode* r;
	char* n;
	ctr_size vlen;
	if (ctr_mode_debug) printf("Parsing STRING. \n");
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_LTRSTRING;
	n = ctr_clex_readstr();
	vlen = ctr_clex_tok_value_length();
	r->value = ctr_malloc(sizeof(char) * vlen, 0);
	memcpy(r->value, n, vlen);
	r->vlen = vlen;
	ctr_clex_tok(); /* eat trailing quote. */
	return r;
}
Example #11
0
/**
 * CTRParserPOpen
 *
 * Generates a set of nested nodes.
 */
ctr_tnode* ctr_cparse_popen() {
	ctr_tnode* r;
	ctr_tlistitem* li;
	int t;
	ctr_clex_tok();
	if (ctr_mode_debug) printf("Parsing paren open (.\n");
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_NESTED;
	li = CTR_PARSER_CREATE_LISTITEM();
	r->nodes = li;
	li->node = ctr_cparse_expr(0);
	t = ctr_clex_tok();
	if (t != CTR_TOKEN_PARCLOSE) {
		printf("Error, expected ). \n");
		exit(1);
	}
	return r;
}
Example #12
0
/**
 * CTRParserBlock
 *
 * Generates a set of AST nodes to represent a block of code.
 */
ctr_tnode* ctr_cparse_block() {
	ctr_tnode* r;
	ctr_tlistitem* codeBlockPart1;
	ctr_tlistitem* codeBlockPart2;
	ctr_tnode* paramList;
	ctr_tnode* codeList;
	ctr_tlistitem* previousListItem;
	ctr_tlistitem* previousCodeListItem;
	int t;
	int first;
	if (ctr_mode_debug) printf("Parsing code block.\n");
	ctr_clex_tok();
	r = CTR_PARSER_CREATE_NODE();
	r->type = CTR_AST_NODE_CODEBLOCK;
	codeBlockPart1 = CTR_PARSER_CREATE_LISTITEM();
	r->nodes = codeBlockPart1;
	codeBlockPart2 = CTR_PARSER_CREATE_LISTITEM();
	r->nodes->next = codeBlockPart2;
	paramList = CTR_PARSER_CREATE_NODE();
	codeList  = CTR_PARSER_CREATE_NODE();	
	codeBlockPart1->node = paramList;
	codeBlockPart2->node = codeList;
	paramList->type = CTR_AST_NODE_PARAMLIST;
	codeList->type = CTR_AST_NODE_INSTRLIST;
	t = ctr_clex_tok();
	first = 1;
	while(t == CTR_TOKEN_REF) {
		ctr_tlistitem* paramListItem = CTR_PARSER_CREATE_LISTITEM();
		ctr_tnode* paramItem = CTR_PARSER_CREATE_NODE();
		long l = ctr_clex_tok_value_length();
		paramItem->value = ctr_malloc(sizeof(char) * l, 0);
		memcpy(paramItem->value, ctr_clex_tok_value(), l);
		paramItem->vlen = l;
		paramListItem->node = paramItem;
		if (first) {
			paramList->nodes = paramListItem;
			previousListItem = paramListItem;
			first = 0;
		} else {
			previousListItem->next = paramListItem;
			previousListItem = paramListItem;
		}
		t = ctr_clex_tok();
	}
	if (t != CTR_TOKEN_BLOCKPIPE) {
		printf("Error expected blockpipe.");
		exit(1);
	}
	t = ctr_clex_tok();
	first = 1;
	while((first || t == CTR_TOKEN_DOT)) {
		ctr_tlistitem* codeListItem;
		ctr_tnode* codeNode;
		if (first) {
			if (ctr_mode_debug) printf("First, so put back\n");
			ctr_clex_putback();
		}
		t = ctr_clex_tok();
		if (t == CTR_TOKEN_BLOCKCLOSE) break;
		ctr_clex_putback();
		codeListItem = CTR_PARSER_CREATE_LISTITEM();
		codeNode = CTR_PARSER_CREATE_NODE();
		if (ctr_mode_debug) printf("--------> %d %s \n", t, ctr_clex_tok_value());
		if (t == CTR_TOKEN_RET) {
			codeNode = ctr_cparse_ret();
		} else {
			codeNode = ctr_cparse_expr(0);
		}
		codeListItem->node = codeNode;
		if (first) {
			codeList->nodes = codeListItem;
			previousCodeListItem = codeListItem;
			first = 0;
		} else {
			previousCodeListItem->next = codeListItem;
			previousCodeListItem = codeListItem;
		}
		t = ctr_clex_tok();
		if (t != CTR_TOKEN_DOT) {
			printf("Expected . but got: %d.\n", t);
			exit(1);
		}
	}
	return r;
}
Example #13
0
/**
 * CTRParserMessage
 *
 * Creates the AST nodes for sending a message.
 *
 * - precedence mode 0: no argument (allows processing of unary message, binary message and keyword message)
 * - precedence mode 1: as argument of keyword message (allows processing of unary message and binary message)
 * - precedence mode 2: as argument of binary message (only allows processing of unary message)
 */
ctr_tnode* ctr_cparse_message(int mode) {
	long msgpartlen; /* length of part of message string */
	ctr_tnode* m;
	int t;
	char* s;
	char* msg;
	ctr_tlistitem* li;
	ctr_tlistitem* curlistitem;
	int lookAhead;
	int isBin;
	int first;
	ctr_size ulen;
	t = ctr_clex_tok();
	msgpartlen = ctr_clex_tok_value_length();
	if ((msgpartlen) > 255) {
		printf("Message too long\n");
		exit(1);
	}
	m = CTR_PARSER_CREATE_NODE();
	m->type = -1;
	s = ctr_clex_tok_value();
	msg = ctr_malloc(255*sizeof(char), 0);
	memcpy(msg, s, msgpartlen);
	ulen = ctr_getutf8len(msg, msgpartlen);
	isBin = (ulen == 1);
	if (mode == 2 && isBin) {
		ctr_clex_putback();
		return m;
	}
	if (isBin) {
		if (ctr_mode_debug) printf("Parsing binary message: '%s' (mode: %d)\n", msg, mode);
		m->type = CTR_AST_NODE_BINMESSAGE;
		m->value = msg;
		m->vlen = msgpartlen;
		li = CTR_PARSER_CREATE_LISTITEM();
		if (ctr_mode_debug) printf("Binary argument start..\n");
		li->node = ctr_cparse_expr(2);
		if (ctr_mode_debug) printf("Binary argument end..\n");
		m->nodes = li;
		return m;
	}
	lookAhead = ctr_clex_tok(); ctr_clex_putback();
	if (lookAhead == CTR_TOKEN_COLON) {
		if (mode > 0) {
			ctr_clex_putback();
			if (ctr_mode_debug) printf("> End of argument, next token: %s .\n", msg);
			return m;
		 }
		*(msg + msgpartlen) = ':';
		msgpartlen += 1;
		if ((msgpartlen) > 255) {
			printf("Message too long\n");
			exit(1);
		}
		if (ctr_mode_debug) printf("Message so far: %s\n", msg);
		m->type = CTR_AST_NODE_KWMESSAGE;
		t = ctr_clex_tok();
		first = 1;
		while(1) {
			li = CTR_PARSER_CREATE_LISTITEM();
			if (ctr_mode_debug) printf("Next arg, message so far: %s \n", msg);
			li->node = ctr_cparse_expr(1);
			if (ctr_mode_debug) printf("Argument of keyword message has been parsed.\n");
			if (first) {
				m->nodes = li;
				curlistitem = m->nodes;
				first = 0;
			} else {
				curlistitem->next = li;
				curlistitem = li;
			}
			t = ctr_clex_tok();
			if (ctr_mode_debug) printf("Next token after argument = %d \n", t);
			if (t == CTR_TOKEN_DOT) break;
			if (t == CTR_TOKEN_FIN) break;
			if (t == CTR_TOKEN_CHAIN) break;
			if (t == CTR_TOKEN_PARCLOSE) break;
			if (t == CTR_TOKEN_REF) {
				long l = ctr_clex_tok_value_length(); 
				if ((msgpartlen + l) > 255) {
					printf("Message too long\n");
					exit(1);
				}
				memcpy( (msg+msgpartlen), ctr_clex_tok_value(), l);
				msgpartlen = msgpartlen + l;
				*(msg + msgpartlen) = ':';
				msgpartlen ++;
				t = ctr_clex_tok();
				if (t != CTR_TOKEN_COLON) {
					printf("Expected colon. %s \n",msg);
					exit(1);
				}
			}
		}
		if (ctr_mode_debug) printf("Putting back.\n");
		ctr_clex_putback(); /* not a colon so put back */
		if (ctr_mode_debug) printf("Parsing keyword message: '%s' (mode: %d) \n", msg, mode);
		m->value = msg;
		m->vlen = msgpartlen;
	} else {
		m->type = CTR_AST_NODE_UNAMESSAGE;
		m->value = msg;
		m->vlen = msgpartlen;
		if (ctr_mode_debug) printf("Parsing unary message: '%s' (mode: %d) token = %d \n", msg, mode, lookAhead);
	}
	return m;
}