Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added 'gnuasm' lexer #2010

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions lib/rouge/demos/gnuasm
@@ -0,0 +1,39 @@
.global main
.type main, @function
.extern printf

.text
/* Reads an integer,
doubles it,
and prints it. */
main:
pushq %rbp
movq %rsp, %rbp
subq $128, %rsp # Reserve 128 bytes for stack

# Read an integer into -8(%rbp)
movq $scan_format, %rdi
leaq -8(%rbp), %rsi
call scanf
# If invalid, jump to end
cmpq $1, %rax
jne .Lend

movq -8(%rbp), %rsi
imulq $2, %rsi # Double the input

# Call 'printf("%ld\n", %rsi)'
movq $print_format, %rdi
call printf

.Lend:
# Return with status 0
movq $0, %rax
movq %rbp, %rsp
popq %rbp
ret

scan_format:
.asciz "%ld"
print_format:
.asciz "%ld\n"
7 changes: 7 additions & 0 deletions lib/rouge/guessers/disambiguation.rb
Expand Up @@ -146,6 +146,13 @@ def match?(filename)
next Prolog if matches?(/\A\w+(\(\w+\,\s*\w+\))*\./)
next OpenEdge
end

disambiguate '*.s', '*.S' do
next GnuAsm if matches?(/\s*\.(global|extern|type|text)/)
next GnuAsm if matches?(/%(r|e)(ax|bx|cx|dx|si|di|bp|sp)/)

ArmAsm
end
end
end
end
3 changes: 2 additions & 1 deletion lib/rouge/lexers/armasm.rb
Expand Up @@ -7,7 +7,8 @@ class ArmAsm < RegexLexer
title "ArmAsm"
desc "Arm assembly syntax"
tag 'armasm'
filenames '*.s'
filenames '*.s', '*.S'
mimetypes 'text/x-asm'

def self.preproc_keyword
@preproc_keyword ||= %w(
Expand Down
64 changes: 64 additions & 0 deletions lib/rouge/lexers/gnuasm.rb
@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

# Derived from nasm.rb. Not perfect.
module Rouge
module Lexers
class GnuAsm < RegexLexer
title "GnuAsm"
desc "GNU Assembler"

tag 'gnuasm'
filenames '*.s', '*.S'
mimetypes 'text/x-asm'

state :root do
mixin :whitespace

rule %r/[a-z$._?][\w$.?#@~]*:/i, Name::Label

rule %r/([a-z$._?][\w$.?#@~]*)(\s+)(equ)/i do
groups Name::Constant, Keyword::Declaration, Keyword::Declaration
push :instruction_args
end
rule %r/\.[a-z0-9]+/i, Keyword, :instruction_args
rule %r/(?:res|d)[bwdqt]|times/i, Keyword::Declaration, :instruction_args
rule %r/[a-z$._?][\w$.?#@~]*/i, Name::Function, :instruction_args

rule %r/[\r\n]+/, Text
end

state :instruction_args do
rule %r/"(\\\\"|[^"\n])*"|'(\\\\'|[^'\n])*'|`(\\\\`|[^`\n])*`/, Str
rule %r/(?:0x[\da-f]+|$0[\da-f]*|\d+[\da-f]*h)/i, Num::Hex
rule %r/[0-7]+q/i, Num::Oct
rule %r/[01]+b/i, Num::Bin
rule %r/\d+\.e?\d+/i, Num::Float
rule %r/\d+/, Num::Integer

rule %r/[@$][a-z$._][\w$.?#@~]*/i, Name::Constant

mixin :punctuation

rule %r/%[a-z0-9]+/i, Name::Builtin
rule %r/[a-z$._][\w$.?#@~]*/i, Name::Variable
rule %r/[\r\n]+/, Text, :pop!

mixin :whitespace
end

state :whitespace do
rule %r/\n/, Text
rule %r/[ \t]+/, Text
rule %r/#.*/, Comment::Single
rule %r/\/\*(.|\n)*?\*\/*/, Comment::Multiline
end

state :punctuation do
rule %r/[,():\[\]]+/, Punctuation
rule %r/[&|^<>+*\/~=-]+/, Operator
rule %r/\$+/, Keyword::Constant
end
end
end
end
4 changes: 2 additions & 2 deletions spec/lexers/armasm_spec.rb
Expand Up @@ -7,8 +7,8 @@
describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.s'
it 'guesses by filename and source hint' do
assert_guess :filename => 'foo.s', :source => 'Func MOVW r0, #RetVal'
end
end
end
14 changes: 14 additions & 0 deletions spec/lexers/gnuasm_spec.rb
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

describe Rouge::Lexers::GnuAsm do
let(:subject) { Rouge::Lexers::GnuAsm.new }

describe 'guessing' do
include Support::Guessing

it 'guesses by filename and source hint' do
assert_guess :filename => 'foo.s', :source => 'main: movq %rax, %rbx'
end
end
end
39 changes: 39 additions & 0 deletions spec/visual/samples/gnuasm
@@ -0,0 +1,39 @@
.global main
.type main, @function
.extern printf

.text
/* Reads an integer,
doubles it,
and prints it. */
main:
pushq %rbp
movq %rsp, %rbp
subq $128, %rsp # Reserve 128 bytes for stack

# Read an integer into -8(%rbp)
movq $scan_format, %rdi
leaq -8(%rbp), %rsi
call scanf
# If invalid, jump to end
cmpq $1, %rax
jne .Lend

movq -8(%rbp), %rsi
imulq $2, %rsi # Double the input

# Call 'printf("%ld\n", %rsi)'
movq $print_format, %rdi
call printf

.Lend:
# Return with status 0
movq $0, %rax
movq %rbp, %rsp
popq %rbp
ret

scan_format:
.asciz "%ld"
print_format:
.asciz "%ld\n"