added while loops and fixed unary operators (including correct precrement and decrement)

This commit is contained in:
Nathan Braswell
2016-01-19 03:16:16 -05:00
parent 4493dfd861
commit ca85edaeee
5 changed files with 75 additions and 33 deletions

View File

@@ -124,7 +124,7 @@ comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ;
expression = expression WS "<<" WS term | expression WS right_shift WS shiftand | shiftand ; expression = expression WS "<<" WS term | expression WS right_shift WS shiftand | shiftand ;
shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ;
term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ;
factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ;
unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda ; unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda ;
number = integer | floating_literal ; number = integer | floating_literal ;
access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ; access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ;

View File

@@ -469,8 +469,8 @@ obj case_statement (Object) {
return true return true
} }
} }
fun ast_while_loop_ptr(): *ast_node { fun ast_while_loop_ptr(condition: *ast_node): *ast_node {
var to_ret.construct(): while_loop var to_ret.construct(condition): while_loop
var ptr = new<ast_node>() var ptr = new<ast_node>()
ptr->copy_construct(&ast_node::while_loop(to_ret)) ptr->copy_construct(&ast_node::while_loop(to_ret))
return ptr return ptr
@@ -482,12 +482,18 @@ fun is_while_loop(node: *ast_node): bool {
return false return false
} }
obj while_loop (Object) { obj while_loop (Object) {
var condition: *ast_node
var statement: *ast_node
var scope: map<string, vector<*ast_node>> var scope: map<string, vector<*ast_node>>
fun construct(): *while_loop { fun construct(condition_in: *ast_node): *while_loop {
condition = condition_in
statement = null<ast_node>()
scope.construct() scope.construct()
return this return this
} }
fun copy_construct(old: *while_loop) { fun copy_construct(old: *while_loop) {
condition = old->condition
statement = old->statement
scope.copy_construct(&old->scope) scope.copy_construct(&old->scope)
} }
fun destruct() { fun destruct() {
@@ -498,7 +504,7 @@ obj while_loop (Object) {
copy_construct(&other) copy_construct(&other)
} }
fun operator==(other: ref while_loop): bool { fun operator==(other: ref while_loop): bool {
return true return condition == other.condition && statement == other.statement
} }
} }
fun ast_for_loop_ptr(): *ast_node { fun ast_for_loop_ptr(): *ast_node {
@@ -890,7 +896,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> {
ast_node::if_statement(backing) return vector(backing.condition, backing.then_part, backing.else_part) ast_node::if_statement(backing) return vector(backing.condition, backing.then_part, backing.else_part)
ast_node::match_statement(backing) return vector<*ast_node>() ast_node::match_statement(backing) return vector<*ast_node>()
ast_node::case_statement(backing) return vector<*ast_node>() ast_node::case_statement(backing) return vector<*ast_node>()
ast_node::while_loop(backing) return vector<*ast_node>() ast_node::while_loop(backing) return vector(backing.condition, backing.statement)
ast_node::for_loop(backing) return vector<*ast_node>() ast_node::for_loop(backing) return vector<*ast_node>()
ast_node::return_statement(backing) return vector(backing.return_value) ast_node::return_statement(backing) return vector(backing.return_value)
ast_node::break_statement(backing) return vector<*ast_node>() ast_node::break_statement(backing) return vector<*ast_node>()

View File

@@ -190,6 +190,8 @@ obj ast_transformation (Object) {
return transform_assignment_statement(node, scope) return transform_assignment_statement(node, scope)
} else if (name == "if_statement") { } else if (name == "if_statement") {
return transform_if_statement(node, scope) return transform_if_statement(node, scope)
} else if (name == "while_loop") {
return transform_while_loop(node, scope)
} else if (name == "return_statement") { } else if (name == "return_statement") {
return transform_return_statement(node, scope) return transform_return_statement(node, scope)
} else if (name == "function_call") { } else if (name == "function_call") {
@@ -300,6 +302,12 @@ obj ast_transformation (Object) {
if_statement->if_statement.else_part = statements[1] if_statement->if_statement.else_part = statements[1]
return if_statement return if_statement
} }
fun transform_while_loop(node: *tree<symbol>, scope: *ast_node): *ast_node {
var while_loop = ast_while_loop_ptr(transform_expression(get_node("boolean_expression", node), scope))
add_to_scope("~enclosing_scope", scope, while_loop)
while_loop->while_loop.statement = transform(get_node("statement", node), while_loop)
return while_loop
}
fun transform_return_statement(node: *tree<symbol>, scope: *ast_node): *ast_node { fun transform_return_statement(node: *tree<symbol>, scope: *ast_node): *ast_node {
return ast_return_statement_ptr(transform(node->children[0], scope)) return ast_return_statement_ptr(transform(node->children[0], scope))
} }
@@ -318,14 +326,26 @@ obj ast_transformation (Object) {
fun transform_expression(node: *tree<symbol>, scope: *ast_node): *ast_node { fun transform_expression(node: *tree<symbol>, scope: *ast_node): *ast_node {
// figure out what the expression is, handle overloads, or you know // figure out what the expression is, handle overloads, or you know
// ignore everything and do a passthrough // ignore everything and do a passthrough
var func_name = string()
var parameters = vector<*ast_node>()
if (node->children.size == 1) if (node->children.size == 1)
return transform(node->children[0], scope) return transform(node->children[0], scope)
else if (node->children.size == 2) { else if (node->children.size == 2) {
return transform(node->children[0], scope) var check_if_post = concat_symbol_tree(node->children[1])
if (check_if_post == "--" || check_if_post == "++") {
// give the post-operators a special suffix so the c_generator knows to emit them post
func_name = concat_symbol_tree(node->children[1]) + "p"
parameters = vector(transform(node->children[0], scope))
} else {
func_name = concat_symbol_tree(node->children[0])
parameters = vector(transform(node->children[1], scope))
}
} else {
func_name = concat_symbol_tree(node->children[1])
parameters = vector(transform(node->children[0], scope), transform(node->children[2], scope))
} }
var parameters = vector(transform(node->children[0], scope), transform(node->children[2], scope))
var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);) var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);)
return ast_function_call_ptr(get_builtin_function(concat_symbol_tree(node->children[1]), parameter_types), parameters) return ast_function_call_ptr(get_builtin_function(func_name, parameter_types), parameters)
} }
fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node { fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>()) return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>())

View File

@@ -99,6 +99,9 @@ obj c_generator (Object) {
if_str += string(" else {\n") + generate(node->if_statement.else_part) + "}" if_str += string(" else {\n") + generate(node->if_statement.else_part) + "}"
return if_str + "\n" return if_str + "\n"
} }
fun generate_while_loop(node: *ast_node): string {
return string("while (") + generate(node->while_loop.condition) + ") {\n" + generate(node->while_loop.statement) + "}\n"
}
fun generate_identifier(node: *ast_node): string { fun generate_identifier(node: *ast_node): string {
return node->identifier.name return node->identifier.name
} }
@@ -121,6 +124,9 @@ obj c_generator (Object) {
var parameters = node->function_call.parameters var parameters = node->function_call.parameters
if (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" || func_name == "||" || func_name == "&&") if (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" || func_name == "||" || func_name == "&&")
return string("(") + generate(parameters[0]) + func_name + generate(parameters[1]) + string(")") return string("(") + generate(parameters[0]) + func_name + generate(parameters[1]) + string(")")
// the post ones need to be post-ed specifically, and take the p off
if (func_name == "++p" || func_name == "--p")
return string("(") + generate(parameters[0]) + ")" + func_name.slice(0,-2)
var call_string = string() var call_string = string()
parameters.for_each(fun(param: *ast_node) { parameters.for_each(fun(param: *ast_node) {
if (call_string != "") if (call_string != "")
@@ -140,6 +146,7 @@ obj c_generator (Object) {
ast_node::declaration_statement(backing) return generate_declaration_statement(node) ast_node::declaration_statement(backing) return generate_declaration_statement(node)
ast_node::assignment_statement(backing) return generate_assignment_statement(node) ast_node::assignment_statement(backing) return generate_assignment_statement(node)
ast_node::if_statement(backing) return generate_if_statement(node) ast_node::if_statement(backing) return generate_if_statement(node)
ast_node::while_loop(backing) return generate_while_loop(node)
ast_node::function(backing) return generate_function(node) ast_node::function(backing) return generate_function(node)
ast_node::function_call(backing) return generate_function_call(node) ast_node::function_call(backing) return generate_function_call(node)
ast_node::code_block(backing) return generate_code_block(node) ast_node::code_block(backing) return generate_code_block(node)

View File

@@ -1,31 +1,40 @@
import to_import: simple_print, a, b import to_import: simple_print, a, b
obj Something (ObjectTrait) { /*obj Something (ObjectTrait) {*/
var member: int /*var member: int*/
fun method():int { /*fun method():int {*/
return 5 /*return 5*/
} /*}*/
} /*}*/
fun some_function(): int return 0; /*fun some_function(): int return 0;*/
fun some_other_function(in: bool): float { /*fun some_other_function(in: bool): float {*/
return 0.0 /*return 0.0*/
} /*}*/
fun main(): int { fun main(): int {
var a_declaration:int /*var a_declaration:int*/
simple_print(1 + 2) /*simple_print(1 + 2)*/
var again = 2 + 4 - 1 * 400 /*var again = 2 + 4 - 1 * 400*/
simple_print(again) /*simple_print(again)*/
again = 2 + (4 - 1) * 400 /*again = 2 + (4 - 1) * 400*/
simple_print(again) /*simple_print(again)*/
var another_declaration: int = 8.0 /*var another_declaration: int = 8.0*/
simple_print(another_declaration) /*simple_print(another_declaration)*/
var yet_another_declaration = "Hello Marcus\n" /*var yet_another_declaration = "Hello Marcus\n"*/
simple_print(yet_another_declaration) /*simple_print(yet_another_declaration)*/
simple_print("Hello World!\n") /*simple_print("Hello World!\n")*/
simple_print(1337) /*simple_print(1337)*/
if (1 + 2 && false) simple_print("its true!") /*if (1 + 2 && false) simple_print("its true!")*/
else simple_print("its false!") /*else simple_print("its false!")*/
var counter = 10
counter--
--counter
while (counter) simple_print(counter--)
simple_print("\n")
counter = 8
while (counter) {
simple_print(--counter)
}
return 0 return 0
} }