Skip to content

Instantly share code, notes, and snippets.

@Andre-LA
Last active December 15, 2020 18:45
Show Gist options
  • Save Andre-LA/c92beb30f6e6ac98c2665b909a075236 to your computer and use it in GitHub Desktop.
Save Andre-LA/c92beb30f6e6ac98c2665b909a075236 to your computer and use it in GitHub Desktop.
nelua trait example
-- based from https://github.com/edubart/nelua-lang/blob/master/lib/allocators/interface.nelua
-- a trait impl. can be just a macro which should receive a record as parameter
## local function sum_fields_trait(R)
-- ensure that the argument is really a record
##[[ staticassert(
R and R.value and R.value.is_record,
"parameter passed to 'sum_fields' is not a record"
)]]
-- mark on the received type that implements the the "sum_fields" trait
## R.value.is_sum_fields = true
-- type alias of the received type
local R: type = #[R]#
-- only implements sum_fields when there aren't already a "sum_fields" metafield
-- (a function declared on a record is a metafield of this record)
## if not R.value.metafields.sum_fields then
-- default "sum_fields" implementation
function R:sum_fields(): number
local result: number = 0
-- generates the sum code, adding one sum
-- for each field with is_arithmetic trait
## for _, field in ipairs(R.value.fields) do
## if field.type.is_arithmetic then
result = result + self.#|field.name|#
## end
## end
return result
end
## end
## end
----------
-- TEST --
----------
local A = @record{ x: integer, s: stringview }
local B = @record{ a: integer, b: integer}
-- this will "override" the default
function B:sum_fields(): number
return (self.a + self.b) * -1000
end
## sum_fields_trait(A)
## sum_fields_trait(B)
local a: A = {10, "hello"}
local b: B = {10, 20}
print('a sum: ', a:sum_fields())
print('b sum: ', b:sum_fields())
-- Prints:
-- a sum: 10
-- b sum: -30000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment