/
externalFunctionDeclaration.st
47 lines (44 loc) · 1.62 KB
/
externalFunctionDeclaration.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
externalFunctionDeclaration
"Parse the function declaration for a call to an external library."
| descriptorClass callType retType externalName args argType module |
descriptorClass := Smalltalk globals at: #ExternalFunction ifAbsent: [ nil ].
descriptorClass == nil
ifTrue: [ ^ false ].
callType := descriptorClass callingConventionFor: currentToken value.
callType == nil
ifTrue: [ ^ false ]. "Parse return type"
self step.
retType := self externalType: descriptorClass.
retType == nil
ifTrue: [ ^ self parserError: 'lack return type' ]. "Parse function name or index"
externalName := currentToken value.
(self match: String)
ifTrue: [ externalName := externalName asSymbol ]
ifFalse: [ (self match: Number)
ifFalse: [ self parserError: 'function name or index' ] ].
(self matchToken: $()
ifFalse: [ ^ self parserError: 'argument list' ].
args := Array new writeStream.
[ currentToken value == $) ]
whileFalse: [
argType := self externalType: descriptorClass.
argType == nil
ifTrue: [ ^ self parserError: 'argument' ].
argType isVoid & argType isPointerType not
ifFalse: [ args nextPut: argType ] ].
(args position = currentScope selector numArgs) ifFalse: [
^self parserError: 'Matching number of arguments'].
(self matchToken: $))
ifFalse: [ ^ self parserError: ')' ].
(self matchToken: 'module:')
ifTrue: [
module := currentToken value.
(self match: String)
ifFalse: [ ^ self parserError: 'String' ].
module := module asSymbol ].
^ RBFFICallPragma
externalName: externalName
module: module
callType: callType
returnType: retType
argumentTypes: args contents