Merge branch 'master' of https://github.com/Limvot/kraken
This commit is contained in:
25
kraken.krak
25
kraken.krak
@@ -8,6 +8,7 @@ import symbol:*
|
|||||||
import tree:*
|
import tree:*
|
||||||
import serialize:*
|
import serialize:*
|
||||||
import c_generator:*
|
import c_generator:*
|
||||||
|
import c_line_control:*
|
||||||
import interpreter:*
|
import interpreter:*
|
||||||
import os:*
|
import os:*
|
||||||
import compiler_version
|
import compiler_version
|
||||||
@@ -24,12 +25,16 @@ fun main(argc: int, argv: **char):int {
|
|||||||
var interpret_instead = false
|
var interpret_instead = false
|
||||||
var argv1_str = string(argv[1])
|
var argv1_str = string(argv[1])
|
||||||
var opt_str = string("-O3")
|
var opt_str = string("-O3")
|
||||||
|
var line_ctrl = false
|
||||||
if (argv1_str == "-i") {
|
if (argv1_str == "-i") {
|
||||||
interpret_instead = true
|
interpret_instead = true
|
||||||
input_file_offset++
|
input_file_offset++
|
||||||
} else if (argv1_str.length() > 2 && argv1_str.slice(0,2) == "-O") {
|
} else if (argv1_str.length() > 2 && argv1_str.slice(0,2) == "-O") {
|
||||||
opt_str = argv1_str
|
opt_str = argv1_str
|
||||||
input_file_offset++
|
input_file_offset++
|
||||||
|
} else if (argv1_str == "-g") {
|
||||||
|
line_ctrl = true
|
||||||
|
input_file_offset++
|
||||||
}
|
}
|
||||||
var kraken_file_name = string(argv[input_file_offset])
|
var kraken_file_name = string(argv[input_file_offset])
|
||||||
var executable_name = string(".").join(kraken_file_name.split('.').slice(0,-2))
|
var executable_name = string(".").join(kraken_file_name.split('.').slice(0,-2))
|
||||||
@@ -77,15 +82,31 @@ fun main(argc: int, argv: **char):int {
|
|||||||
println("done writing")
|
println("done writing")
|
||||||
}
|
}
|
||||||
|
|
||||||
var parse.construct(gram): parser
|
var parse1.construct(&gram): parser
|
||||||
|
/*var parse2.construct(&gram): parser*/
|
||||||
|
/*var parse3.construct(&gram): parser*/
|
||||||
|
/*var parse4.construct(&gram): parser*/
|
||||||
|
/*var parse5.construct(&gram): parser*/
|
||||||
|
/*var parse6.construct(&gram): parser*/
|
||||||
|
/*var parse7.construct(&gram): parser*/
|
||||||
|
/*var parse8.construct(&gram): parser*/
|
||||||
var ast_pass.construct(): ast_transformation
|
var ast_pass.construct(): ast_transformation
|
||||||
var importer.construct(parse, ast_pass, vector(string(), base_dir + "/stdlib/")): importer
|
var parsers = vector(parse1)
|
||||||
|
/*var parsers = vector(parse1,parse2,parse3,parse4)*/
|
||||||
|
/*var parsers = vector(parse1,parse2,parse3,parse4,parse5,parse6)*/
|
||||||
|
/*var parsers = vector(parse1,parse2,parse3,parse4,parse5,parse6,parse7,parse8)*/
|
||||||
|
var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer
|
||||||
importer.import(kraken_file_name)
|
importer.import(kraken_file_name)
|
||||||
if (interpret_instead) {
|
if (interpret_instead) {
|
||||||
printlnerr("Interpreting!")
|
printlnerr("Interpreting!")
|
||||||
var interpret.construct(importer.name_ast_map, importer.ast_pass.ast_to_syntax): interpreter
|
var interpret.construct(importer.name_ast_map, importer.ast_pass.ast_to_syntax): interpreter
|
||||||
interpret.call_main()
|
interpret.call_main()
|
||||||
} else {
|
} else {
|
||||||
|
if (line_ctrl) {
|
||||||
|
printlnerr("running C-specific passes")
|
||||||
|
printlnerr("running #line")
|
||||||
|
c_line_control(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
||||||
|
}
|
||||||
printlnerr("Generating C")
|
printlnerr("Generating C")
|
||||||
var c_generator.construct(): c_generator
|
var c_generator.construct(): c_generator
|
||||||
var c_output_pair = c_generator.generate_c(importer.name_ast_map, importer.ast_pass.ast_to_syntax)
|
var c_output_pair = c_generator.generate_c(importer.name_ast_map, importer.ast_pass.ast_to_syntax)
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ obj translation_unit (Object) {
|
|||||||
return children == other.children && name == other.name && lambdas == other.lambdas
|
return children == other.children && name == other.name && lambdas == other.lambdas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_import_ptr(name: string, translation_unit: *ast_node): *ast_node {
|
fun ast_import_ptr(name: string, containing_tu: *ast_node): *ast_node {
|
||||||
var to_ret.construct(name, translation_unit): import
|
var to_ret.construct(name, containing_tu): import
|
||||||
var ptr = new<ast_node>()
|
var ptr = new<ast_node>()
|
||||||
ptr->copy_construct(&ast_node::import(to_ret))
|
ptr->copy_construct(&ast_node::import(to_ret))
|
||||||
return ptr
|
return ptr
|
||||||
@@ -111,14 +111,16 @@ fun is_import(node: *ast_node): bool {
|
|||||||
obj import (Object) {
|
obj import (Object) {
|
||||||
var scope: map<string, vector<*ast_node>>
|
var scope: map<string, vector<*ast_node>>
|
||||||
var imported: set<string>
|
var imported: set<string>
|
||||||
|
var containing_translation_unit: *ast_node
|
||||||
var translation_unit: *ast_node
|
var translation_unit: *ast_node
|
||||||
var name: string
|
var name: string
|
||||||
var starred: bool
|
var starred: bool
|
||||||
fun construct(nameIn: string, translation_unit_in: *ast_node): *import {
|
fun construct(nameIn: string, containing_tu: *ast_node): *import {
|
||||||
scope.construct()
|
scope.construct()
|
||||||
imported.construct()
|
imported.construct()
|
||||||
name.copy_construct(&nameIn)
|
name.copy_construct(&nameIn)
|
||||||
translation_unit = translation_unit_in
|
containing_translation_unit = containing_tu
|
||||||
|
translation_unit = null<ast_node>()
|
||||||
starred = false
|
starred = false
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -126,6 +128,7 @@ obj import (Object) {
|
|||||||
scope.copy_construct(&old->scope)
|
scope.copy_construct(&old->scope)
|
||||||
imported.copy_construct(&old->imported)
|
imported.copy_construct(&old->imported)
|
||||||
name.copy_construct(&old->name)
|
name.copy_construct(&old->name)
|
||||||
|
containing_translation_unit = old->containing_translation_unit
|
||||||
translation_unit = old->translation_unit
|
translation_unit = old->translation_unit
|
||||||
starred = old->starred
|
starred = old->starred
|
||||||
}
|
}
|
||||||
@@ -139,7 +142,7 @@ obj import (Object) {
|
|||||||
copy_construct(&other)
|
copy_construct(&other)
|
||||||
}
|
}
|
||||||
fun operator==(other: ref import): bool {
|
fun operator==(other: ref import): bool {
|
||||||
return imported == other.imported && name == other.name && translation_unit == other.translation_unit && starred == other.starred
|
return imported == other.imported && name == other.name && containing_translation_unit == other.containing_translation_unit && translation_unit == other.translation_unit && starred == other.starred
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun ast_identifier_ptr(name: *char, type: *type, enclosing_scope: *ast_node): *ast_node {
|
fun ast_identifier_ptr(name: *char, type: *type, enclosing_scope: *ast_node): *ast_node {
|
||||||
|
|||||||
@@ -42,9 +42,8 @@ obj ast_transformation (Object) {
|
|||||||
fourth_pass_worklist.destruct()
|
fourth_pass_worklist.destruct()
|
||||||
}
|
}
|
||||||
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs
|
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs
|
||||||
fun first_pass(file_name: string, parse_tree: *tree<symbol>, importer: *importer): *ast_node {
|
fun first_pass(file_name: string, parse_tree: *tree<symbol>, importer: *importer): pair<*ast_node, vector<*ast_node>> {
|
||||||
var translation_unit = ast_translation_unit_ptr(file_name)
|
var translation_unit = ast_translation_unit_ptr(file_name)
|
||||||
importer->register(file_name, parse_tree, translation_unit)
|
|
||||||
parse_tree->children.for_each(fun(child: *tree<symbol>) {
|
parse_tree->children.for_each(fun(child: *tree<symbol>) {
|
||||||
if (child->data.name == "type_def") {
|
if (child->data.name == "type_def") {
|
||||||
translation_unit->translation_unit.children.add(first_pass_type_def(child, translation_unit, false))
|
translation_unit->translation_unit.children.add(first_pass_type_def(child, translation_unit, false))
|
||||||
@@ -63,15 +62,16 @@ obj ast_transformation (Object) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// now do all imports (done second so that if it imports this translation_unit,
|
// now do all imports
|
||||||
// this one already has all its types defined
|
// re return a vector of them so importer can fix them (and our translation unit scope)
|
||||||
|
// up with actual pointers to the other ASTs
|
||||||
|
var imports = vector<*ast_node>()
|
||||||
parse_tree->children.for_each(fun(child: *tree<symbol>) {
|
parse_tree->children.for_each(fun(child: *tree<symbol>) {
|
||||||
if (child->data.name == "import") {
|
if (child->data.name == "import") {
|
||||||
var import_identifier_children = get_nodes("identifier", child)
|
var import_identifier_children = get_nodes("identifier", child)
|
||||||
var name = concat_symbol_tree(import_identifier_children[0])
|
var name = concat_symbol_tree(import_identifier_children[0])
|
||||||
var outside_translation_unit = importer->import_first_pass(name + ".krak")
|
var import_node = ast_import_ptr(name, translation_unit)
|
||||||
add_to_scope(name, outside_translation_unit, translation_unit)
|
imports.add(import_node)
|
||||||
var import_node = ast_import_ptr(name, outside_translation_unit)
|
|
||||||
translation_unit->translation_unit.children.add(import_node)
|
translation_unit->translation_unit.children.add(import_node)
|
||||||
ast_to_syntax.set(import_node, child)
|
ast_to_syntax.set(import_node, child)
|
||||||
add_to_scope("~enclosing_scope", translation_unit, import_node)
|
add_to_scope("~enclosing_scope", translation_unit, import_node)
|
||||||
@@ -80,7 +80,7 @@ obj ast_transformation (Object) {
|
|||||||
import_node->import.starred = true
|
import_node->import.starred = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return translation_unit
|
return make_pair(translation_unit, imports)
|
||||||
}
|
}
|
||||||
fun transform_traits(traits_node: *tree<symbol>): set<string> {
|
fun transform_traits(traits_node: *tree<symbol>): set<string> {
|
||||||
if (!traits_node)
|
if (!traits_node)
|
||||||
@@ -600,7 +600,11 @@ obj ast_transformation (Object) {
|
|||||||
new_passthrough->simple_passthrough.linker_str = concat_symbol_tree(linker_str).slice(1,-2)
|
new_passthrough->simple_passthrough.linker_str = concat_symbol_tree(linker_str).slice(1,-2)
|
||||||
return new_passthrough
|
return new_passthrough
|
||||||
}
|
}
|
||||||
fun transform_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node return ast_statement_ptr(transform(node->children[0], scope, template_replacements));
|
fun transform_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
||||||
|
var to_ret = ast_statement_ptr(transform(node->children[0], scope, template_replacements));
|
||||||
|
ast_to_syntax.set(to_ret, node)
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
fun transform_declaration_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
fun transform_declaration_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
||||||
// this might have an init position method call
|
// this might have an init position method call
|
||||||
var identifiers = get_nodes("identifier", node)
|
var identifiers = get_nodes("identifier", node)
|
||||||
|
|||||||
@@ -995,7 +995,7 @@ obj c_generator (Object) {
|
|||||||
ast_node::value(backing) return generate_value(node, need_variable)
|
ast_node::value(backing) return generate_value(node, need_variable)
|
||||||
ast_node::identifier(backing) return generate_identifier(node, enclosing_object, enclosing_func)
|
ast_node::identifier(backing) return generate_identifier(node, enclosing_object, enclosing_func)
|
||||||
}
|
}
|
||||||
error("/* COULD NOT GENERATE */")
|
error(string("COULD NOT GENERATE ") + get_ast_name(node))
|
||||||
return code_triple("/* COULD NOT GENERATE */")
|
return code_triple("/* COULD NOT GENERATE */")
|
||||||
}
|
}
|
||||||
fun type_decoration(type: *type): string {
|
fun type_decoration(type: *type): string {
|
||||||
@@ -1053,19 +1053,21 @@ obj c_generator (Object) {
|
|||||||
base_type::adt() return get_name(type->type_def) + indirection
|
base_type::adt() return get_name(type->type_def) + indirection
|
||||||
base_type::function() {
|
base_type::function() {
|
||||||
// maybe disregard indirection in the future?
|
// maybe disregard indirection in the future?
|
||||||
if (function_type_map.contains_key(*type))
|
type = type->clone_with_indirection(0,false)
|
||||||
return function_type_map[*type]
|
if (!function_type_map.contains_key(*type)) {
|
||||||
var temp_name = string("function_struct") + get_id()
|
var temp_name = string("function_struct") + get_id()
|
||||||
var temp = string()
|
var temp = string()
|
||||||
type->parameter_types.for_each(fun(parameter_type: *type) temp += string(", ") + type_to_c(parameter_type) + " ";)
|
type->parameter_types.for_each(fun(parameter_type: *type) temp += string(", ") + type_to_c(parameter_type) + " ";)
|
||||||
var with_data = string("typedef ") + type_to_c(type->return_type) + " (*" + temp_name + "_with_data)(void*" + temp + ");\n"
|
var with_data = string("typedef ") + type_to_c(type->return_type) + " (*" + temp_name + "_with_data)(void*" + temp + ");\n"
|
||||||
var without_data = string("typedef ") + type_to_c(type->return_type) + " (*" + temp_name + "_without_data)(" + temp.slice(1,-1) + ");\n"
|
var without_data = string("typedef ") + type_to_c(type->return_type) + " (*" + temp_name + "_without_data)(" + temp.slice(1,-1) + ");\n"
|
||||||
function_typedef_string += with_data
|
function_typedef_string += with_data
|
||||||
function_typedef_string += without_data
|
function_typedef_string += without_data
|
||||||
function_typedef_string += string("typedef struct {\nvoid* data;\n") + temp_name + "_with_data func;\n} " + temp_name + ";\n"
|
function_typedef_string += string("typedef struct {\nvoid* data;\n") + temp_name + "_with_data func;\n} " + temp_name + ";\n"
|
||||||
// again, the indirection
|
function_typedef_string += string("/* ") + type->to_string() + " */\n"
|
||||||
function_type_map[*type] = temp_name+indirection
|
// again, the indirection
|
||||||
return temp_name + indirection
|
function_type_map[*type] = temp_name
|
||||||
|
}
|
||||||
|
return function_type_map[*type] + indirection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string("impossible type") + indirection
|
return string("impossible type") + indirection
|
||||||
|
|||||||
76
stdlib/c_line_control.krak
Normal file
76
stdlib/c_line_control.krak
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import symbol:*
|
||||||
|
import tree:*
|
||||||
|
import vector:*
|
||||||
|
import map:*
|
||||||
|
import util:*
|
||||||
|
import string:*
|
||||||
|
import mem:*
|
||||||
|
import io:*
|
||||||
|
import ast_nodes:*
|
||||||
|
import ast_transformation:*
|
||||||
|
|
||||||
|
fun get_line(node: *tree<symbol>, name: string): *ast_node {
|
||||||
|
var to_ret = ast_simple_passthrough_ptr()
|
||||||
|
to_ret->simple_passthrough.passthrough_str = string("\n#line ") + get_first_terminal(node)->data.position + " \"" + name + "\"\n"
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add_before_in(to_add: *ast_node, before: *ast_node, in: *ast_node) {
|
||||||
|
var bc = null<vector<*ast_node>>()
|
||||||
|
match(*in) {
|
||||||
|
ast_node::translation_unit(backing) bc = &in->translation_unit.children
|
||||||
|
ast_node::code_block(backing) bc = &in->code_block.children
|
||||||
|
}
|
||||||
|
if (bc) {
|
||||||
|
for (var i = 0; i < bc->size; i++;) {
|
||||||
|
if ((*bc)[i] == before) {
|
||||||
|
/*println("\nbefore\n")*/
|
||||||
|
/*(*bc).for_each(fun(n:*ast_node) println(get_ast_name(n));)*/
|
||||||
|
/*(*bc).for_each(fun(n:*ast_node) println(n);)*/
|
||||||
|
(*bc).add(to_add, i)
|
||||||
|
/*println("\nafter\n")*/
|
||||||
|
/*(*bc).for_each(fun(n:*ast_node) println(get_ast_name(n));)*/
|
||||||
|
/*(*bc).for_each(fun(n:*ast_node) println(n);)*/
|
||||||
|
/*println("\n")*/
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error(string("cannot add_before_in to ") + get_ast_name(in))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun c_line_control(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
|
var first = true
|
||||||
|
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
||||||
|
var helper: fun(*ast_node, *ast_node):void = fun(node: *ast_node, parent: *ast_node) {
|
||||||
|
if (!node) return
|
||||||
|
match(*node) {
|
||||||
|
ast_node::translation_unit(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::type_def(backing) {
|
||||||
|
/*println(string("adding ") + get_ast_name(node) + " to " + get_ast_name(parent))*/
|
||||||
|
/*add_before_in(get_line(), node, parent)*/
|
||||||
|
/*get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)*/
|
||||||
|
}
|
||||||
|
ast_node::function(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::code_block(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::statement(backing) {
|
||||||
|
if (is_code_block(parent) && ast_to_syntax->contains_key(node)) {
|
||||||
|
/*println(string("adding ") + get_ast_name(node) + " to " + get_ast_name(parent))*/
|
||||||
|
add_before_in(get_line(ast_to_syntax->get(node), name), node, parent)
|
||||||
|
}
|
||||||
|
get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
}
|
||||||
|
ast_node::if_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::match_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::case_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::while_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
ast_node::for_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (first)
|
||||||
|
helper(syntax_ast_pair.second, null<ast_node>())
|
||||||
|
first = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -10,21 +10,22 @@ import io:*
|
|||||||
import ast_nodes:*
|
import ast_nodes:*
|
||||||
import ast_transformation:*
|
import ast_transformation:*
|
||||||
import parser:*
|
import parser:*
|
||||||
|
import thread:*
|
||||||
|
|
||||||
obj importer (Object) {
|
obj importer (Object) {
|
||||||
var parse: parser
|
var parsers: vector<parser>
|
||||||
var ast_pass: ast_transformation
|
var ast_pass: ast_transformation
|
||||||
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
|
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
|
||||||
var import_paths: vector<string>
|
var import_paths: vector<string>
|
||||||
fun construct(parseIn: ref parser, ast_passIn: ref ast_transformation, import_paths_in: vector<string>): *importer {
|
fun construct(parsersIn: ref vector<parser>, ast_passIn: ref ast_transformation, import_paths_in: vector<string>): *importer {
|
||||||
parse.copy_construct(&parseIn)
|
parsers.copy_construct(&parsersIn)
|
||||||
ast_pass.copy_construct(&ast_passIn)
|
ast_pass.copy_construct(&ast_passIn)
|
||||||
name_ast_map.construct()
|
name_ast_map.construct()
|
||||||
import_paths.copy_construct(&import_paths_in)
|
import_paths.copy_construct(&import_paths_in)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
fun copy_construct(old: *importer) {
|
fun copy_construct(old: *importer) {
|
||||||
parse.copy_construct(&old->parse)
|
parsers.copy_construct(&old->parsers)
|
||||||
ast_pass.copy_construct(&old->ast_pass)
|
ast_pass.copy_construct(&old->ast_pass)
|
||||||
name_ast_map.copy_construct(&old->name_ast_map)
|
name_ast_map.copy_construct(&old->name_ast_map)
|
||||||
import_paths.copy_construct(&old->import_paths)
|
import_paths.copy_construct(&old->import_paths)
|
||||||
@@ -34,15 +35,66 @@ obj importer (Object) {
|
|||||||
copy_construct(&old)
|
copy_construct(&old)
|
||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
parse.destruct()
|
parsers.destruct()
|
||||||
ast_pass.destruct()
|
ast_pass.destruct()
|
||||||
name_ast_map.destruct()
|
name_ast_map.destruct()
|
||||||
import_paths.destruct()
|
import_paths.destruct()
|
||||||
}
|
}
|
||||||
fun import(file_name: string): *ast_node {
|
fun import(file_name: string) {
|
||||||
|
// lambda closes over our fix-up list
|
||||||
|
var imports_to_fix = vector<*ast_node>()
|
||||||
|
var import_first_pass = fun(file_name_idx: pair<string,int>) {
|
||||||
|
var file_name = file_name_idx.first
|
||||||
|
var file = string()
|
||||||
|
import_paths.for_each(fun(path: string) {
|
||||||
|
if (file_exists(path + file_name)) {
|
||||||
|
file = read_file(path + file_name)
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
printerr(file_name + ", ")
|
||||||
|
var parse_tree = parsers[file_name_idx.second].parse_input(file, file_name)
|
||||||
|
trim(parse_tree)
|
||||||
|
var ast_and_imports = ast_pass.first_pass(file_name, parse_tree, this)
|
||||||
|
imports_to_fix += ast_and_imports.second
|
||||||
|
name_ast_map[file_name] = make_pair(parse_tree, ast_and_imports.first)
|
||||||
|
}
|
||||||
printlnerr("**First Pass**")
|
printlnerr("**First Pass**")
|
||||||
printerr("parsing: ")
|
printerr("parsing: ")
|
||||||
var to_ret = import_first_pass(file_name)
|
import_first_pass(make_pair(file_name,0))
|
||||||
|
for (var i = 0; i < imports_to_fix.size; i++;) {
|
||||||
|
/*println(string("iteration of imports to fix: ") + i)*/
|
||||||
|
var threads = vector<*ulong>()
|
||||||
|
var num_threads = min(imports_to_fix.size - i, parsers.size)
|
||||||
|
for (var j = i; j < i+num_threads; j++;) {
|
||||||
|
var import_name = imports_to_fix[j]->import.name
|
||||||
|
var file_name = import_name + ".krak"
|
||||||
|
if (!name_ast_map.contains_key(file_name)) {
|
||||||
|
/*import_first_pass(file_name)*/
|
||||||
|
/*join(run(import_first_pass, file_name))*/
|
||||||
|
if (num_threads > 1)
|
||||||
|
threads.add(run(import_first_pass, make_pair(file_name, j-i)))
|
||||||
|
else
|
||||||
|
import_first_pass(make_pair(file_name,0))
|
||||||
|
} else {
|
||||||
|
threads.add(null<ulong>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*println(string("iteration of imports to fix: ") + i + " made")*/
|
||||||
|
for (var j = i; j < i+num_threads; j++;) {
|
||||||
|
if (num_threads > 1) {
|
||||||
|
if (threads[j-i])
|
||||||
|
join(threads[j-i])
|
||||||
|
}
|
||||||
|
var im = imports_to_fix[j]
|
||||||
|
var import_name = im->import.name
|
||||||
|
var file_name = import_name + ".krak"
|
||||||
|
im->import.translation_unit = name_ast_map[file_name].second
|
||||||
|
add_to_scope(import_name, im->import.translation_unit, im->import.containing_translation_unit)
|
||||||
|
}
|
||||||
|
/*println(string("iteration of imports to fix: ") + i + " done")*/
|
||||||
|
i += num_threads-1
|
||||||
|
}
|
||||||
printlnerr()
|
printlnerr()
|
||||||
printlnerr("**Second Pass**")
|
printlnerr("**Second Pass**")
|
||||||
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.second_pass(tree_pair.first, tree_pair.second);)
|
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.second_pass(tree_pair.first, tree_pair.second);)
|
||||||
@@ -51,49 +103,6 @@ obj importer (Object) {
|
|||||||
// this needs to be modified to do chaotic iteration on instantiating template classes, based on what I see in the C++ version
|
// this needs to be modified to do chaotic iteration on instantiating template classes, based on what I see in the C++ version
|
||||||
printlnerr("**Fourth Pass**")
|
printlnerr("**Fourth Pass**")
|
||||||
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.fourth_pass(tree_pair.first, tree_pair.second);)
|
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.fourth_pass(tree_pair.first, tree_pair.second);)
|
||||||
|
|
||||||
/*
|
|
||||||
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) {
|
|
||||||
print("writing ast for: "); println(name)
|
|
||||||
write_file(name + ".ast.dot", ast_to_dot(tree_pair.second))
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
return to_ret
|
|
||||||
}
|
|
||||||
fun import_first_pass(file_name: string): *ast_node {
|
|
||||||
if (name_ast_map.contains_key(file_name))
|
|
||||||
return name_ast_map[file_name].second
|
|
||||||
|
|
||||||
/*print("pre-parse: "); println(file_name)*/
|
|
||||||
var file = string()
|
|
||||||
import_paths.for_each(fun(path: string) {
|
|
||||||
/*println(string("Checking ") + path + " for " + file_name)*/
|
|
||||||
if (file_exists(path + file_name)) {
|
|
||||||
/*println("Found it!")*/
|
|
||||||
file = read_file(path + file_name)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
/*println("did not find it")*/
|
|
||||||
}
|
|
||||||
})
|
|
||||||
printerr(file_name + ", ")
|
|
||||||
var parse_tree = parse.parse_input(file, file_name)
|
|
||||||
/*print("post-parse: "); println(file_name)*/
|
|
||||||
/*write_file(file_name + ".parse.dot", syntax_tree_to_dot(parse_tree))*/
|
|
||||||
/*print("pre-trim: "); println(file_name)*/
|
|
||||||
trim(parse_tree)
|
|
||||||
/*print("post-trim: "); println(file_name)*/
|
|
||||||
/*write_file(file_name + ".trimmed_parse.dot", syntax_tree_to_dot(parse_tree))*/
|
|
||||||
/*print("pre-first-ast: "); println(file_name)*/
|
|
||||||
var ast = ast_pass.first_pass(file_name, parse_tree, this)
|
|
||||||
/*print("post-first-ast: "); println(file_name)*/
|
|
||||||
return ast
|
|
||||||
}
|
|
||||||
fun register(file_name: string, parse_tree: *tree<symbol>, translation_unit: *ast_node) {
|
|
||||||
name_ast_map.set(file_name, make_pair(parse_tree, translation_unit))
|
|
||||||
/*print("Registered parse_tree+translation_unit for ")*/
|
|
||||||
/*println(file_name)*/
|
|
||||||
}
|
}
|
||||||
fun trim(parse_tree: *tree<symbol>) {
|
fun trim(parse_tree: *tree<symbol>) {
|
||||||
remove_node(symbol("$NULL$", false), parse_tree)
|
remove_node(symbol("$NULL$", false), parse_tree)
|
||||||
|
|||||||
@@ -656,7 +656,7 @@ obj interpreter (Object) {
|
|||||||
return make_pair(value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection())), control_flow::nor())
|
return make_pair(value::variable(make_pair(get_real_value(dereference_val).pointer.first, dereference_val.pointer.second->clone_with_decreased_indirection())), control_flow::nor())
|
||||||
}
|
}
|
||||||
// check for built-in-ish externs (everything the standard library needs)
|
// check for built-in-ish externs (everything the standard library needs)
|
||||||
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "fflush" || func_name == "snprintf" || func_name == "fopen" || func_name == "fclose" || func_name == "ftell" || func_name == "fseek" || func_name == "fread" || func_name == "fwrite" || func_name == "atan" || func_name == "atan2" || func_name == "acos" || func_name == "asin" || func_name == "tan" || func_name == "cos" || func_name == "sin")
|
if (func_name == "printf" || func_name == "malloc" || func_name == "free" || func_name == "memmove" || func_name == "fflush" || func_name == "snprintf" || func_name == "fopen" || func_name == "fclose" || func_name == "ftell" || func_name == "fseek" || func_name == "fread" || func_name == "fwrite" || func_name == "atan" || func_name == "atan2" || func_name == "acos" || func_name == "asin" || func_name == "tan" || func_name == "cos" || func_name == "sin")
|
||||||
return make_pair(call_built_in_extern(func_name, parameters), control_flow::nor())
|
return make_pair(call_built_in_extern(func_name, parameters), control_flow::nor())
|
||||||
if (!func_call_func->function.body_statement)
|
if (!func_call_func->function.body_statement)
|
||||||
error(string("trying to call unsupported extern function: ") + func_name)
|
error(string("trying to call unsupported extern function: ") + func_name)
|
||||||
@@ -764,6 +764,9 @@ obj interpreter (Object) {
|
|||||||
} else if (func_name == "free") {
|
} else if (func_name == "free") {
|
||||||
assert(parameters.size == 1 && is_pointer(parameters[0]), "Calling free with wrong params")
|
assert(parameters.size == 1 && is_pointer(parameters[0]), "Calling free with wrong params")
|
||||||
free(parameters[0].pointer.first)
|
free(parameters[0].pointer.first)
|
||||||
|
} else if (func_name == "memmove") {
|
||||||
|
assert(parameters.size == 3 && is_pointer(parameters[0]) && is_pointer(parameters[1]) && is_ulong_int(parameters[2]), "Calling memmove with wrong params")
|
||||||
|
return value::pointer(make_pair(memmove((parameters[0].pointer.first) cast *void, (parameters[1].pointer.first) cast *void, parameters[2].ulong_int), type_ptr(base_type::void_return(), 1)))
|
||||||
} else if (func_name == "fflush") {
|
} else if (func_name == "fflush") {
|
||||||
assert(parameters.size == 1 && is_integer(parameters[0]), "Calling fflush with wrong params")
|
assert(parameters.size == 1 && is_integer(parameters[0]), "Calling fflush with wrong params")
|
||||||
fflush(parameters[0].integer)
|
fflush(parameters[0].integer)
|
||||||
@@ -884,7 +887,7 @@ obj interpreter (Object) {
|
|||||||
}
|
}
|
||||||
error("bad branch type")
|
error("bad branch type")
|
||||||
}
|
}
|
||||||
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
|
fun interpret_code_block(block: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
|
||||||
var_stack->push(map<*ast_node,value>())
|
var_stack->push(map<*ast_node,value>())
|
||||||
var defer_stack = stack<*ast_node>()
|
var defer_stack = stack<*ast_node>()
|
||||||
for (var i = 0; i < block->code_block.children.size; i++;) {
|
for (var i = 0; i < block->code_block.children.size; i++;) {
|
||||||
@@ -1025,7 +1028,7 @@ obj interpreter (Object) {
|
|||||||
ast_node::while_loop(backing) return interpret_while_loop(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::while_loop(backing) return interpret_while_loop(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||||
ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object, enclosing_func)
|
ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::branching_statement(backing) return interpret_branching_statement(node)
|
ast_node::branching_statement(backing) return interpret_branching_statement(node)
|
||||||
ast_node::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::code_block(backing) return interpret_code_block(node, var_stack, enclosing_object, enclosing_func)
|
||||||
ast_node::return_statement(backing) return interpret_return_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::return_statement(backing) return interpret_return_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||||
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::declaration_statement(backing) return interpret_declaration_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||||
ast_node::assignment_statement(backing) return interpret_assignment_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
ast_node::assignment_statement(backing) return interpret_assignment_statement(node, var_stack, enclosing_object, enclosing_func, defer_stack)
|
||||||
|
|||||||
@@ -35,11 +35,6 @@ fun print(toPrint: *char) : void {
|
|||||||
fun println()
|
fun println()
|
||||||
print("\n")
|
print("\n")
|
||||||
|
|
||||||
fun print<T>(toPrint: *T) {
|
|
||||||
print("ptr:<")
|
|
||||||
print((toPrint) cast ulong)
|
|
||||||
print(">")
|
|
||||||
}
|
|
||||||
fun print(toPrint: char) : void
|
fun print(toPrint: char) : void
|
||||||
print(string::string(toPrint))
|
print(string::string(toPrint))
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import io:*
|
|||||||
|
|
||||||
obj parser (Object) {
|
obj parser (Object) {
|
||||||
var input: vector<symbol>
|
var input: vector<symbol>
|
||||||
var gram: grammer
|
var gram: *grammer
|
||||||
var gss: gss
|
var gss: gss
|
||||||
var to_reduce: stack<reduction>
|
var to_reduce: stack<reduction>
|
||||||
var to_shift: stack< pair<*tree<int>, int> >
|
var to_shift: stack< pair<*tree<int>, int> >
|
||||||
@@ -21,9 +21,9 @@ obj parser (Object) {
|
|||||||
var packed_map: map<*tree<symbol>, bool>
|
var packed_map: map<*tree<symbol>, bool>
|
||||||
var reduces_to_null_map: map<vector<symbol>, bool>
|
var reduces_to_null_map: map<vector<symbol>, bool>
|
||||||
|
|
||||||
fun construct(grammerIn: grammer): *parser {
|
fun construct(grammerIn: *grammer): *parser {
|
||||||
input.construct()
|
input.construct()
|
||||||
gram.copy_construct(&grammerIn)
|
gram = grammerIn
|
||||||
gss.construct()
|
gss.construct()
|
||||||
to_reduce.construct()
|
to_reduce.construct()
|
||||||
to_shift.construct()
|
to_shift.construct()
|
||||||
@@ -32,9 +32,12 @@ obj parser (Object) {
|
|||||||
reduces_to_null_map.construct()
|
reduces_to_null_map.construct()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
fun construct(): *parser {
|
||||||
|
return construct(null<grammer>())
|
||||||
|
}
|
||||||
fun copy_construct(old: *parser) {
|
fun copy_construct(old: *parser) {
|
||||||
input.copy_construct(&old->input)
|
input.copy_construct(&old->input)
|
||||||
gram.copy_construct(&old->gram)
|
gram = old->gram
|
||||||
gss.copy_construct(&old->gss)
|
gss.copy_construct(&old->gss)
|
||||||
to_reduce.copy_construct(&old->to_reduce)
|
to_reduce.copy_construct(&old->to_reduce)
|
||||||
to_shift.copy_construct(&old->to_shift)
|
to_shift.copy_construct(&old->to_shift)
|
||||||
@@ -48,7 +51,6 @@ obj parser (Object) {
|
|||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
input.destruct()
|
input.destruct()
|
||||||
gram.destruct()
|
|
||||||
gss.destruct()
|
gss.destruct()
|
||||||
to_reduce.destruct()
|
to_reduce.destruct()
|
||||||
to_shift.destruct()
|
to_shift.destruct()
|
||||||
@@ -68,13 +70,13 @@ obj parser (Object) {
|
|||||||
// if the zero state contains any reductions for state 0 and eof, then
|
// if the zero state contains any reductions for state 0 and eof, then
|
||||||
// it must be reducing to the goal state
|
// it must be reducing to the goal state
|
||||||
/*println("checking the bidness")*/
|
/*println("checking the bidness")*/
|
||||||
if (inputStr == "" && gram.parse_table.get(0, eof_symbol()).contains(action(action_type::reduce(), 0))) {
|
if (inputStr == "" && gram->parse_table.get(0, eof_symbol()).contains(action(action_type::reduce(), 0))) {
|
||||||
println("Accept on no input for ")
|
println("Accept on no input for ")
|
||||||
println(name)
|
println(name)
|
||||||
return new<tree<symbol>>()->construct(null_symbol())
|
return new<tree<symbol>>()->construct(null_symbol())
|
||||||
}
|
}
|
||||||
|
|
||||||
var lex = lexer(gram.terminals)
|
var lex = lexer(gram->terminals)
|
||||||
lex.set_input(inputStr)
|
lex.set_input(inputStr)
|
||||||
var current_symbol.construct(): symbol
|
var current_symbol.construct(): symbol
|
||||||
for (current_symbol = lex.next(); current_symbol != eof_symbol() && current_symbol != invalid_symbol(); current_symbol = lex.next();) {
|
for (current_symbol = lex.next(); current_symbol != eof_symbol() && current_symbol != invalid_symbol(); current_symbol = lex.next();) {
|
||||||
@@ -97,7 +99,7 @@ obj parser (Object) {
|
|||||||
|
|
||||||
var null_symbol_tree = null<tree<symbol>>()
|
var null_symbol_tree = null<tree<symbol>>()
|
||||||
|
|
||||||
gram.parse_table.get(0, input[0]).for_each(fun(act: action) {
|
gram->parse_table.get(0, input[0]).for_each(fun(act: action) {
|
||||||
/*println("for each action")
|
/*println("for each action")
|
||||||
act.print()
|
act.print()
|
||||||
*/
|
*/
|
||||||
@@ -108,7 +110,7 @@ obj parser (Object) {
|
|||||||
/*print("act == reduce() && == 0 Adding reduction from state: ")
|
/*print("act == reduce() && == 0 Adding reduction from state: ")
|
||||||
println(v0->data)
|
println(v0->data)
|
||||||
*/
|
*/
|
||||||
to_reduce.push(reduction(v0, gram.rules[act.state_or_rule].lhs, 0, null_symbol_tree, null_symbol_tree))
|
to_reduce.push(reduction(v0, gram->rules[act.state_or_rule].lhs, 0, null_symbol_tree, null_symbol_tree))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -190,11 +192,11 @@ obj parser (Object) {
|
|||||||
// the shift lookup will fail, and likely other things, and this is our accept
|
// the shift lookup will fail, and likely other things, and this is our accept
|
||||||
// criteria anyway
|
// criteria anyway
|
||||||
/*if (curr_reached->data == 0 && curr_reduction.sym == gram.rules[0].lhs)*/
|
/*if (curr_reached->data == 0 && curr_reduction.sym == gram.rules[0].lhs)*/
|
||||||
if (curr_reduction.sym == gram.rules[0].lhs) {
|
if (curr_reduction.sym == gram->rules[0].lhs) {
|
||||||
/*println("would accept here")*/
|
/*println("would accept here")*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var shift_to = gram.parse_table.get_shift(curr_reached->data, curr_reduction.sym).state_or_rule
|
var shift_to = gram->parse_table.get_shift(curr_reached->data, curr_reduction.sym).state_or_rule
|
||||||
/*println("got shift to")*/
|
/*println("got shift to")*/
|
||||||
var new_label = null<tree<symbol>>()
|
var new_label = null<tree<symbol>>()
|
||||||
if (curr_reduction.length == 0) {
|
if (curr_reduction.length == 0) {
|
||||||
@@ -219,10 +221,10 @@ obj parser (Object) {
|
|||||||
gss.add_edge(shift_to_node, curr_reached, new_label)
|
gss.add_edge(shift_to_node, curr_reached, new_label)
|
||||||
// do non-null reductions
|
// do non-null reductions
|
||||||
if (curr_reduction.length) {
|
if (curr_reduction.length) {
|
||||||
gram.parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
|
gram->parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
|
||||||
/*if (act.act == reduce && !fully_reduces_to_null(reduce_rule)) {*/
|
/*if (act.act == reduce && !fully_reduces_to_null(reduce_rule)) {*/
|
||||||
if (act.act == action_type::reduce() && act.rule_position != 0) {
|
if (act.act == action_type::reduce() && act.rule_position != 0) {
|
||||||
var reduce_rule = gram.rules[act.state_or_rule]
|
var reduce_rule = gram->rules[act.state_or_rule]
|
||||||
to_reduce.push(reduction(curr_reached, reduce_rule.lhs,
|
to_reduce.push(reduction(curr_reached, reduce_rule.lhs,
|
||||||
act.rule_position,
|
act.rule_position,
|
||||||
get_nullable_parts(reduce_rule),
|
get_nullable_parts(reduce_rule),
|
||||||
@@ -238,11 +240,11 @@ obj parser (Object) {
|
|||||||
shift_to_node = gss.new_node(shift_to)
|
shift_to_node = gss.new_node(shift_to)
|
||||||
gss.add_to_frontier(i, shift_to_node)
|
gss.add_to_frontier(i, shift_to_node)
|
||||||
gss.add_edge(shift_to_node, curr_reached, new_label)
|
gss.add_edge(shift_to_node, curr_reached, new_label)
|
||||||
gram.parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
|
gram->parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
|
||||||
if (act.act == action_type::push()) {
|
if (act.act == action_type::push()) {
|
||||||
to_shift.push(make_pair(shift_to_node, act.state_or_rule))
|
to_shift.push(make_pair(shift_to_node, act.state_or_rule))
|
||||||
} else {
|
} else {
|
||||||
var action_rule = gram.rules[act.state_or_rule]
|
var action_rule = gram->rules[act.state_or_rule]
|
||||||
// tricky tricky tricky. Fully reduces to null is not the same as act.rule_position being 0
|
// tricky tricky tricky. Fully reduces to null is not the same as act.rule_position being 0
|
||||||
/*if (fully_reduces_to_null(action_rule)) {*/
|
/*if (fully_reduces_to_null(action_rule)) {*/
|
||||||
if (act.rule_position == 0) {
|
if (act.rule_position == 0) {
|
||||||
@@ -287,8 +289,8 @@ obj parser (Object) {
|
|||||||
println(i+1)
|
println(i+1)
|
||||||
*/
|
*/
|
||||||
gss.add_edge(shift_to_node, shift.first, new_label)
|
gss.add_edge(shift_to_node, shift.first, new_label)
|
||||||
gram.parse_table.get_reduces(shift.second, input[i+1]).for_each(fun(action: action) {
|
gram->parse_table.get_reduces(shift.second, input[i+1]).for_each(fun(action: action) {
|
||||||
var reduce_rule = gram.rules[action.state_or_rule]
|
var reduce_rule = gram->rules[action.state_or_rule]
|
||||||
/*if (!fully_reduces_to_null(reduce_rule)) {*/
|
/*if (!fully_reduces_to_null(reduce_rule)) {*/
|
||||||
if (action.rule_position != 0) {
|
if (action.rule_position != 0) {
|
||||||
to_reduce.push(reduction(shift.first, reduce_rule.lhs, action.rule_position,
|
to_reduce.push(reduction(shift.first, reduce_rule.lhs, action.rule_position,
|
||||||
@@ -308,14 +310,14 @@ obj parser (Object) {
|
|||||||
/*println("post add to frontier")*/
|
/*println("post add to frontier")*/
|
||||||
gss.add_edge(shift_to_node, shift.first, new_label)
|
gss.add_edge(shift_to_node, shift.first, new_label)
|
||||||
/*println("post add edger")*/
|
/*println("post add edger")*/
|
||||||
gram.parse_table.get(shift.second, input[i+1]).for_each(fun(action: action) {
|
gram->parse_table.get(shift.second, input[i+1]).for_each(fun(action: action) {
|
||||||
/*println("looking at an action")*/
|
/*println("looking at an action")*/
|
||||||
if (action.act == action_type::push()) {
|
if (action.act == action_type::push()) {
|
||||||
/*println("is push")*/
|
/*println("is push")*/
|
||||||
next_shifts.push(make_pair(shift_to_node, action.state_or_rule))
|
next_shifts.push(make_pair(shift_to_node, action.state_or_rule))
|
||||||
} else {
|
} else {
|
||||||
/*println("is reduce")*/
|
/*println("is reduce")*/
|
||||||
var action_rule = gram.rules[action.state_or_rule]
|
var action_rule = gram->rules[action.state_or_rule]
|
||||||
/*if (!fully_reduces_to_null(action_rule)) {*/
|
/*if (!fully_reduces_to_null(action_rule)) {*/
|
||||||
if (action.rule_position != 0) {
|
if (action.rule_position != 0) {
|
||||||
/*println("does not reduce to null")*/
|
/*println("does not reduce to null")*/
|
||||||
@@ -391,7 +393,7 @@ obj parser (Object) {
|
|||||||
}
|
}
|
||||||
fun reduces_to_null(r: ref rule): bool {
|
fun reduces_to_null(r: ref rule): bool {
|
||||||
if (!reduces_to_null_map.contains_key(r.rhs))
|
if (!reduces_to_null_map.contains_key(r.rhs))
|
||||||
reduces_to_null_map[r.rhs] = gram.first_vector(r.rhs).contains(null_symbol())
|
reduces_to_null_map[r.rhs] = gram->first_vector(r.rhs).contains(null_symbol())
|
||||||
return reduces_to_null_map[r.rhs]
|
return reduces_to_null_map[r.rhs]
|
||||||
}
|
}
|
||||||
fun get_nullable_parts(r: ref rule): *tree<symbol> {
|
fun get_nullable_parts(r: ref rule): *tree<symbol> {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ fun to_string(in: long): string
|
|||||||
return to_string_num(in)
|
return to_string_num(in)
|
||||||
fun to_string(in: ulong): string
|
fun to_string(in: ulong): string
|
||||||
return to_string_num(in)
|
return to_string_num(in)
|
||||||
|
fun to_string<T>(in: *T): string
|
||||||
|
return string("ptr:<") + to_string_num((in) cast ulong) + ">"
|
||||||
|
|
||||||
fun string_to_int(it: string): int {
|
fun string_to_int(it: string): int {
|
||||||
var is_negative = false
|
var is_negative = false
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fun run<T>(func :fun(T): void, data: T) : *ulong {
|
|||||||
// to avoid extra copy etc
|
// to avoid extra copy etc
|
||||||
var func_copy = new<fun(T):void>()
|
var func_copy = new<fun(T):void>()
|
||||||
var func_and_data = new<pair<*void, *T>>()->construct()
|
var func_and_data = new<pair<*void, *T>>()->construct()
|
||||||
*data_copy = data
|
maybe_copy_construct(data_copy, &data)
|
||||||
memmove((func_copy) cast *void, (&func) cast *void, #sizeof<fun(T):void>)
|
memmove((func_copy) cast *void, (&func) cast *void, #sizeof<fun(T):void>)
|
||||||
*func_and_data = make_pair((func_copy) cast *void, data_copy)
|
*func_and_data = make_pair((func_copy) cast *void, data_copy)
|
||||||
var wrapper = fun(func_and_data: *void): *void {
|
var wrapper = fun(func_and_data: *void): *void {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ obj vector<T> (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy_construct(old: *vector<T>): void {
|
fun copy_construct(old: *vector<T>): void {
|
||||||
construct(old->size)
|
construct(old->available)
|
||||||
size = old->size
|
size = old->size
|
||||||
if (is_object<T>()) {
|
if (is_object<T>()) {
|
||||||
for (var i = 0; i < old->size; i++;)
|
for (var i = 0; i < old->size; i++;)
|
||||||
@@ -213,12 +213,26 @@ obj vector<T> (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
fun add(dataIn: ref T): void { addEnd(dataIn); }
|
fun add(dataIn: ref T): void { addEnd(dataIn); }
|
||||||
fun addEnd(dataIn: ref T): void {
|
fun addEnd(dataIn: ref T): void {
|
||||||
if (size+1 >= available)
|
// if we resize, we need to be careful as the dataIn reference
|
||||||
|
// may come from this itself
|
||||||
|
if (size+1 > available) {
|
||||||
|
var temp = dataIn
|
||||||
resize((size+1)*2);
|
resize((size+1)*2);
|
||||||
maybe_copy_construct(&data[size], &dataIn);
|
maybe_copy_construct(&data[size], &temp);
|
||||||
|
} else {
|
||||||
|
maybe_copy_construct(&data[size], &dataIn);
|
||||||
|
}
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun add(dataIn: ref T, index: int) {
|
||||||
|
add(last())
|
||||||
|
for (var i = size-2; i > index; i--;) {
|
||||||
|
data[i] = data[i-1]
|
||||||
|
}
|
||||||
|
data[index] = dataIn
|
||||||
|
}
|
||||||
|
|
||||||
fun remove(index: int) {
|
fun remove(index: int) {
|
||||||
maybe_destruct(&data[index])
|
maybe_destruct(&data[index])
|
||||||
for (var i = index+1; i < size; i++;) {
|
for (var i = index+1; i < size; i++;) {
|
||||||
|
|||||||
Reference in New Issue
Block a user