Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Created November 11, 2016 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterDuke17/c1d5414410f070cd04a4d78700dde223 to your computer and use it in GitHub Desktop.
Save MasterDuke17/c1d5414410f070cd04a4d78700dde223 to your computer and use it in GitHub Desktop.
nqp line directives
diff --git a/src/HLL/Actions.nqp b/src/HLL/Actions.nqp
index b2cdcfd..e8a33cd 100644
--- a/src/HLL/Actions.nqp
+++ b/src/HLL/Actions.nqp
@@ -224,4 +224,9 @@ class HLL::Actions {
!! self.string_to_int( $/, 10 )
);
}
+
+ method line_directive($/) {
+ my $orig_line := HLL::Compiler.lineof(~$/.orig(), $/.from(), :cache(1));
+ $*W.add_comp_files_to_directives($orig_line, [nqp::radix(10, $<line>, 0, 0)[0], $<filename>]);
+ }
}
diff --git a/src/HLL/Compiler.nqp b/src/HLL/Compiler.nqp
index b605706..aff983f 100644
--- a/src/HLL/Compiler.nqp
+++ b/src/HLL/Compiler.nqp
@@ -617,7 +617,7 @@ class HLL::Compiler does HLL::Backend::Default {
if $cache {
$*LINEPOSCACHE := $linepos;
}
- my str $s := ~$target;
+ my str $s := $target;
my int $eos := nqp::chars($s);
my int $jpos := 0;
my int $ord;
@@ -662,7 +662,7 @@ class HLL::Compiler does HLL::Backend::Default {
}
method lineof($target, int $pos, int :$cache = 0) {
- nqp::atpos_i(self.line_and_column_of($target, $pos, :$cache), 0);
+ my int $line := nqp::atpos_i(self.line_and_column_of($target, $pos, :$cache), 0);
}
diff --git a/src/HLL/Grammar.nqp b/src/HLL/Grammar.nqp
index 7e85f1c..fa0bf27 100644
--- a/src/HLL/Grammar.nqp
+++ b/src/HLL/Grammar.nqp
@@ -127,6 +127,10 @@ grammar HLL::Grammar {
]
}
+ token line_directive {
+ ^^ '#' \s* 'line' \s+ $<line>=(\d+) \s* $<filename>=(\S+) $$
+ }
+
=begin
=item O(*%spec)
diff --git a/src/HLL/World.nqp b/src/HLL/World.nqp
index e972a47..254dbdf 100644
--- a/src/HLL/World.nqp
+++ b/src/HLL/World.nqp
@@ -82,6 +82,10 @@ class HLL::World {
has $!is_nested;
+ # Mapping of files being compiled to a list of any line number/filename directives
+ # in the files.
+ my %*comp_lines_to_directives := nqp::hash();
+
method BUILD(:$handle!, :$description = '<unknown>', :$context) {
if $context {
$!context := $context;
@@ -181,4 +185,8 @@ class HLL::World {
method fixup_tasks() {
$!context.fixup_tasks
}
+
+ method add_comp_lines_to_directives($comp_line, @directive) {
+ %*comp_lines_to_directives{$comp_line} := @directive;
+ }
}
diff --git a/src/vm/moar/QAST/QASTCompilerMAST.nqp b/src/vm/moar/QAST/QASTCompilerMAST.nqp
index b05ea54..05cce41 100644
--- a/src/vm/moar/QAST/QASTCompilerMAST.nqp
+++ b/src/vm/moar/QAST/QASTCompilerMAST.nqp
@@ -20,6 +20,9 @@ my class MASTCompilerInstance {
# The most recent op we tried to compile, for error reporting.
has $!last_op;
+ # original source file lines
+ has %!source_lines;
+
# This uses a very simple scheme. Write registers are assumed
# to be write-once, read-once. Therefore, if a QAST control
# structure wants to reuse the intermediate result of an
@@ -1402,9 +1405,28 @@ my class MASTCompilerInstance {
# Annotate with line number if we have one.
my $node := $_.node;
if nqp::isconcrete($node) && nqp::can($node,'orig') {
- my $line := HLL::Compiler.lineof($node.orig(), $node.from(), :cache(1));
+ my str $target := ~$node.orig();
+ my int $pos := $node.from();
+ my str $file := $!file;
+# my str $line_comment := "\n#line 1 ";
+# my int $sf_index_s := nqp::rindex($target, $line_comment, $pos);
+# if $sf_index_s >= 0 {
+# my int $i := $sf_index_s + nqp::chars($line_comment);
+# $file := nqp::substr($target, $i, nqp::index($target, "\n", $i) - $i);
+# }
+ my int $s_line := 0;
+# if $sf_index_s >= 0 {
+# if nqp::existskey(%!source_lines, $sf_index_s) {
+# $s_line := %!source_lines{$sf_index_s};
+# }
+# else {
+# $s_line := HLL::Compiler.lineof($target, $sf_index_s, :cache(1)) - 1;
+# %!source_lines{$sf_index_s} := $s_line;
+# }
+# }
+ my $line := HLL::Compiler.lineof($target, $pos, :cache(1)) - $s_line;
nqp::push(@all_ins, MAST::Annotated.new(
- :$!file, :$line, :instructions($last_stmt.instructions) ));
+ :$file, :$line, :instructions($last_stmt.instructions) ));
}
else {
nqp::splice(@all_ins, $last_stmt.instructions, +@all_ins, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment