Create a simple wrapper around liblex and libds.

This commit is contained in:
Danila Fedorin 2018-07-22 16:15:15 -07:00
parent 71a441f11d
commit 7a8f46407a
2 changed files with 105 additions and 0 deletions

50
src/lex/lexer.cr Normal file
View File

@ -0,0 +1,50 @@
require "./lib.cr"
module Lex
class Lexer
def initialize
@config = LibLex::EvalConfig.new
LibLex.eval_config_init(pointerof(@config))
end
def add_pattern(pattern : String, id : Int32)
LibLex.eval_config_add(pointerof(@config), pattern, id)
end
def lex(string)
# Initialize variables
tokens = [] of Tuple(String, Int32)
list = LibDs::Ll.new
# Initialize the list the list
LibDs.ll_init(pointerof(list))
# Perform the lexing operation
result = LibLex.eval_all(string, 0,
pointerof(@config),
pointerof(list))
# Transform void* matches into actual tuples.
if result == LibLex::Result::Success
node = list.head
while node
match = node.value.data.as(LibLex::Match*)
str = string[match.value.from...match.value.to]
tokens << { str, match.value.pattern }
node = node.value.next
end
end
# Clean up.
LibDs.ll_foreach(pointerof(list), nil,
->LibDs.compare_always,
->LibLex.eval_foreach_match_free)
LibDs.ll_free(pointerof(list))
return tokens
end
def finalize
LibLex.eval_config_free(pointerof(@config))
end
end
end

55
src/lex/lib.cr Normal file
View File

@ -0,0 +1,55 @@
@[Link(ldflags: "#{__DIR__}/../../external/liblex/build/external/libds/libds.a")]
lib LibDs
struct LlNode
next: LlNode*
prev: LlNode*
data: Void*
end
struct Ll
head: LlNode*
tail: LlNode*
end
enum Result
Success,
Malloc
end
fun compare_always(a: Void*, b: Void*): Int32
fun ll_init(list: Ll*)
fun ll_foreach(list: Ll*, compare_to: Void*,
compare: Void*, Void* -> Int32,
foreach: Void*, LibC::VaList-> Int32, ...): Int32
fun ll_free(list: Ll*)
end
@[Link(ldflags: "#{__DIR__}/../../external/liblex/build/liblex.a #{__DIR__}/../../external/liblex/build/external/libds/libds.a")]
lib LibLex
struct EvalConfig
stats: LibDs::Ll
end
struct Match
from: LibC::SizeT
to: LibC::SizeT
pattern: Int32
end
enum Result
Success,
Malloc,
Invalid,
Unrecognized
end
fun eval_config_init(config: EvalConfig*)
fun eval_config_add(config: EvalConfig*, string: UInt8*, id: Int32): Result
fun eval_all(string: UInt8*, index: LibC::SizeT, config: EvalConfig*,
matches: LibDs::Ll*): Result
fun eval_config_remove(config: EvalConfig*, string: UInt8*,
id: Int32): Result
fun eval_config_free(config: EvalConfig*): Result
fun eval_foreach_match_free(match: Void*, args: LibC::VaList): Int32
end