1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basic/sberrors.hxx>
25 // test if there's an I/O channel
27 bool SbiParser::Channel( bool bAlways
)
33 SbiExpression
aExpr( this );
34 while( Peek() == COMMA
|| Peek() == SEMICOLON
)
37 aGen
.Gen( SbiOpcode::CHANNEL_
);
41 Error( ERRCODE_BASIC_EXPECTED
, "#" );
45 // it's tried that at object variables the Default-
46 // Property is addressed for PRINT and WRITE
48 void SbiParser::Print()
50 bool bChan
= Channel();
54 if( !IsEoln( Peek() ) )
56 std::unique_ptr
<SbiExpression
> pExpr(new SbiExpression( this ));
60 aGen
.Gen( eCurTok
== COMMA
? SbiOpcode::PRINTF_
: SbiOpcode::BPRINT_
);
62 if( eCurTok
== COMMA
|| eCurTok
== SEMICOLON
)
65 if( IsEoln( Peek() ) ) break;
69 aGen
.Gen( SbiOpcode::PRCHAR_
, '\n' );
74 aGen
.Gen( SbiOpcode::CHAN0_
);
77 // WRITE #chan, expr, ...
79 void SbiParser::Write()
81 bool bChan
= Channel();
85 std::unique_ptr
<SbiExpression
> pExpr(new SbiExpression( this ));
88 aGen
.Gen( SbiOpcode::BWRITE_
);
91 aGen
.Gen( SbiOpcode::PRCHAR_
, ',' );
93 if( IsEoln( Peek() ) ) break;
97 aGen
.Gen( SbiOpcode::PRCHAR_
, '\n' );
102 aGen
.Gen( SbiOpcode::CHAN0_
);
106 // #i92642 Handle LINE keyword outside ::Next()
107 void SbiParser::Line()
109 // #i92642: Special handling to allow name as symbol
110 if( Peek() == INPUT
)
119 KeywordSymbolInfo aInfo
;
120 aInfo
.m_aKeywordSymbol
= "line";
121 aInfo
.m_eSbxDataType
= GetType();
128 // LINE INPUT [prompt], var$
130 void SbiParser::LineInput()
133 std::unique_ptr
<SbiExpression
> pExpr(new SbiExpression( this, SbOPERAND
));
134 if( !pExpr
->IsVariable() )
135 Error( ERRCODE_BASIC_VAR_EXPECTED
);
136 if( pExpr
->GetType() != SbxVARIANT
&& pExpr
->GetType() != SbxSTRING
)
137 Error( ERRCODE_BASIC_CONVERSION
);
139 aGen
.Gen( SbiOpcode::LINPUT_
);
141 aGen
.Gen( SbiOpcode::CHAN0_
); // ResetChannel() not in StepLINPUT() anymore
146 void SbiParser::Input()
148 aGen
.Gen( SbiOpcode::RESTART_
);
150 std::unique_ptr
<SbiExpression
> pExpr(new SbiExpression( this, SbOPERAND
));
153 if( !pExpr
->IsVariable() )
154 Error( ERRCODE_BASIC_VAR_EXPECTED
);
156 aGen
.Gen( SbiOpcode::INPUT_
);
157 if( Peek() == COMMA
)
160 pExpr
.reset(new SbiExpression( this, SbOPERAND
));
165 aGen
.Gen( SbiOpcode::CHAN0_
);
168 // OPEN stringexpr FOR mode ACCESS access mode AS Channel [Len=n]
170 void SbiParser::Open()
173 SbiExpression
aFileName( this );
176 StreamMode nMode
= StreamMode::NONE
;
177 SbiStreamFlags nFlags
= SbiStreamFlags::NONE
;
181 nMode
= StreamMode::READ
; nFlags
|= SbiStreamFlags::Input
; break;
183 nMode
= StreamMode::WRITE
| StreamMode::TRUNC
; nFlags
|= SbiStreamFlags::Output
; break;
185 nMode
= StreamMode::WRITE
; nFlags
|= SbiStreamFlags::Append
; break;
187 nMode
= StreamMode::READ
| StreamMode::WRITE
; nFlags
|= SbiStreamFlags::Random
; break;
189 nMode
= StreamMode::READ
| StreamMode::WRITE
; nFlags
|= SbiStreamFlags::Binary
; break;
191 Error( ERRCODE_BASIC_SYNTAX
);
193 if( Peek() == ACCESS
)
197 // influence only READ,WRITE-Flags in nMode
198 nMode
&= ~StreamMode(StreamMode::READ
| StreamMode::WRITE
); // delete
201 if( Peek() == WRITE
)
204 nMode
|= StreamMode::READ
| StreamMode::WRITE
;
207 nMode
|= StreamMode::READ
;
209 else if( eTok
== WRITE
)
210 nMode
|= StreamMode::WRITE
;
212 Error( ERRCODE_BASIC_SYNTAX
);
217 Next(); nMode
|= StreamMode::SHARE_DENYNONE
; break;
223 if( Peek() == WRITE
)
226 nMode
|= StreamMode::SHARE_DENYALL
;
228 else nMode
|= StreamMode::SHARE_DENYREAD
;
230 else if( eTok
== WRITE
)
231 nMode
|= StreamMode::SHARE_DENYWRITE
;
233 Error( ERRCODE_BASIC_SYNTAX
);
239 std::unique_ptr
<SbiExpression
> pChan(new SbiExpression( this ));
240 std::unique_ptr
<SbiExpression
> pLen
;
241 if( Peek() == SYMBOL
)
244 if( aSym
.equalsIgnoreAsciiCase("LEN") )
247 pLen
.reset(new SbiExpression( this ));
250 if( !pLen
) pLen
.reset(new SbiExpression( this, 128, SbxINTEGER
));
251 // the stack for the OPEN command looks as follows:
258 aGen
.Gen( SbiOpcode::OPEN_
, static_cast<sal_uInt32
>(nMode
), static_cast<sal_uInt32
>(nFlags
) );
259 bInStatement
= false;
264 void SbiParser::Name()
266 // #i92642: Special handling to allow name as symbol
271 KeywordSymbolInfo aInfo
;
272 aInfo
.m_aKeywordSymbol
= "name";
273 aInfo
.m_eSbxDataType
= GetType();
278 SbiExpression
aExpr1( this );
280 SbiExpression
aExpr2( this );
283 aGen
.Gen( SbiOpcode::RENAME_
);
288 void SbiParser::Close()
291 if( IsEoln( eCurTok
) )
292 aGen
.Gen( SbiOpcode::CLOSE_
, 0 );
296 SbiExpression
aExpr( this );
297 while( Peek() == COMMA
|| Peek() == SEMICOLON
)
300 aGen
.Gen( SbiOpcode::CHANNEL_
);
301 aGen
.Gen( SbiOpcode::CLOSE_
, 1 );
303 if( IsEoln( Peek() ) )
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */