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

C++の実装を追加 #9

Merged
merged 12 commits into from
Aug 16, 2022
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trim_trailing_whitespace = true
charset = utf-8-bom
end_of_line = crlf

[*.{csproj,vbproj,proj,props,targets}]
[*.{csproj,vbproj,vcxproj,proj,props,targets}]
charset = utf-8-bom
indent_size = 2
end_of_line = crlf
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/run-tests-impls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
shell: pwsh
run: |
$verbose = '${{ inputs.verbose }}' -ieq 'true'
$target_impls = Get-Content ./tests/impls/implementations.jsonc | ConvertFrom-Json | Select-Object -ExpandProperty ID
$target_impls = Get-Content ./tests/impls/implementations.jsonc | ConvertFrom-Json | Select-Object -ExpandProperty ID | Get-Unique

if ( ! [string]::IsNullOrEmpty( '${{ inputs.target-impl }}' ) ) {
$target_impls = @('${{ inputs.target-impl }}')
Expand Down Expand Up @@ -153,6 +153,10 @@ jobs:
with:
node-version: ${{ env.NODEJS_MINIMUM_VERSION }}

- name: Setup MSBuild
if: ${{ runner.os == 'Windows' && matrix.target-impl == 'cpp' }}
uses: microsoft/[email protected]

- name: Run tests with ${{ matrix.target-impl }} on ${{ matrix.os }}
shell: pwsh
run: |
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
現在、以下の言語の実装があります。

- [C](src/impls/c/)
- [C++](src/impls/cpp/)
- [C#](src/impls/csharp/)
- [Java](src/impls/java/)
- [JavaScript](src/impls/javascript/)
Expand Down
15 changes: 15 additions & 0 deletions src/impls/cpp/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# EditorConfig is awesome: https://EditorConfig.org

[*.cpp]
indent_style = space
indent_size = 4

# ref: https://docs.microsoft.com/ja-jp/visualstudio/ide/cpp-editorconfig-properties
cpp_new_line_before_open_brace_type = same_line
cpp_new_line_before_open_brace_function = new_line
cpp_new_line_before_open_brace_block = same_line
cpp_new_line_before_else = true
cpp_indent_preserve_comments = true
cpp_indent_case_labels = true
cpp_space_around_assignment_operator = ignore
cpp_space_pointer_reference_alignment = left
4 changes: 4 additions & 0 deletions src/impls/cpp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
polish
polish.o
/Debug/
/Release/
23 changes: 23 additions & 0 deletions src/impls/cpp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
CC = g++
#CC = clang++
CFLAGS = -std=c++2a -O4 -Wall -I/usr/local/include

all: polish

polish: polish.o
$(CC) polish.o -o polish

polish.o: polish.cpp
$(CC) $(CFLAGS) -c polish.cpp

clean:
rm -f *.o polish

run: polish
@if [ -z "${INPUT}" ]; then \
./polish; \
fi

@if [ -n "${INPUT}" ]; then \
echo ${INPUT} | ./polish; \
fi
85 changes: 85 additions & 0 deletions src/impls/cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
[二分木を使った数式の逆ポーランド記法化と計算](https://smdn.jp/programming/tips/polish/)のC++での実装。

# 前提条件・依存関係
C++コンパイラが必要です。

`Makefile`を使用してビルド・実行する場合は、`g++`が必要です。

# ビルドおよび実行
## `make`コマンドを使用する場合
コマンド`make run INPUT=(式)`を実行することで、`INPUT`に与えられた式に対して逆ポーランド記法化・計算を行うことができます。

実行例:
```sh
$ make run INPUT='x=1+2'
input expression: expression: x=1+2
reverse polish notation: x 1 2 + =
infix notation: (x = (1 + 2))
polish notation: = x + 1 2
calculated expression: (x = 3)
```

その他、`make`コマンドで以下の操作を行うことができます。

```sh
make # ソースファイルをコンパイルする
make run # ソースファイルをコンパイルして実行する
make clean # 成果物ファイルを削除する
```

## MSBuildを使用する場合
コマンド`msbuild`を実行することでビルドすることができます。 `Debug\polish.exe`が生成されるので、それを実行することで逆ポーランド記法化・計算を行うことができます。

```bat
> msbuild
(中略)
ビルドに成功しました。
0 個の警告
0 エラー

経過時間 00:00:01.31

> Debug\polish.exe
input expression: x=1+2
expression: x=1+2
reverse polish notation: x 1 2 + =
infix notation: (x = (1 + 2))
polish notation: = x + 1 2
calculated expression: (x = 3)
```

その他、`msbuild`コマンドの`/t`オプションで以下の操作を行うことができます。

```bat
msbuild /t:Build # ソースファイルをコンパイルする(/t:Buildは省略できます)
msbuild /t:Clean # 成果物ファイルを削除する
```

`msbuild`コマンドを使用する場合は、`PATH`環境変数に`msbuild.exe`のあるディレクトリを追加しておく必要があります。

スクリプト`find-msbuild.ps1`を実行することで、`msbuild.exe`のパスを検索することができます。

```bat
> .\find-msbuild.ps1
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe
```

## g++でのコンパイル・実行方法
```sh
g++ -std=c++2a polish.cpp -o polish # ソースファイルをコンパイルする
./polish # コンパイルした実行可能ファイルを実行する
```

## Clangでのコンパイル・実行方法
```sh
clang++ -std=c++2a polish.cpp -o polish # ソースファイルをコンパイルする
./polish # コンパイルした実行可能ファイルを実行する
```

### Clangのインストール方法
Ubuntuの場合:
```sh
sudo apt install clang
```
61 changes: 61 additions & 0 deletions src/impls/cpp/find-msbuild.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-FileCopyrightText: 2022 smdn <[email protected]>
# SPDX-License-Identifier: MIT
#
# This script is based on 'MSBuilsSearch_impl.ps1' from https://github.com/rot-z/MSBuildSearch, published under the MIT Lisence.
#

# folder paths of Visual Studio
$MSBUILD_VS2022_BUILDTOOLS_PATH = "Microsoft Visual Studio`\2022`\BuildTools`\MSBuild`\Current`\Bin"
$MSBUILD_VS2019_BUILDTOOLS_PATH = "Microsoft Visual Studio`\2019`\BuildTools`\MSBuild`\Current`\Bin"
$MSBUILD_17_ENTERPRISE_PATH = "Microsoft Visual Studio`\2022`\Enterprise`\MSBuild`\Current`\Bin" # Visual Studio 2022 Enterprise
$MSBUILD_16_COMMUNITY_PATH = "Microsoft Visual Studio`\2019`\Community`\MSBuild`\Current`\Bin" # Visual Studio 2019 Community (not tested)
$MSBUILD_16_PROFESSIONAL_PATH = "Microsoft Visual Studio`\2019`\Professional`\MSBuild`\Current`\Bin" # Visual Studio 2019 Professional
$MSBUILD_15_COMMUNITY_PATH = "Microsoft Visual Studio`\2017`\Community`\MSBuild`\15.0`\Bin" # Visual Studio 2017 Community
$MSBUILD_15_PROFESSIONAL_PATH = "Microsoft Visual Studio`\2017`\Professional`\MSBuild`\15.0`\Bin" # Visual Studio 2017 Professional

# target paths for MSBuild
# sort by priority
[array]$SEARCH_PATHS = @(
$MSBUILD_VS2022_BUILDTOOLS_PATH,
$MSBUILD_VS2019_BUILDTOOLS_PATH,
$MSBUILD_17_ENTERPRISE_PATH,
$MSBUILD_16_COMMUNITY_PATH,
$MSBUILD_16_PROFESSIONAL_PATH,
$MSBUILD_15_COMMUNITY_PATH,
$MSBUILD_15_PROFESSIONAL_PATH
)

# get full path of "Program Files" folder from OS archtechture
$programFilesDir = ""
if ($([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture) -eq 'X64')
{
$programFilesDir = ${env:ProgramFiles(x86)}
}
else
{
$programFilesDir = ${env:ProgramFiles}
}

# search MSBuild.exe
$msbuildPath = ""
foreach($p in $SEARCH_PATHS)
{
# is folder exists?
$targetPath = Join-Path $programFilesDir $p
if (!(Test-Path $targetPath))
{
continue
}

# select the most shortest (shallowest) path
$results = (Get-ChildItem $targetPath -Include MSBuild.exe -Recurse).FullName | Sort-Object -Property Length
if ($results.Length -gt 0)
{
$msbuildPath = $results[0]
Write-Output $msbuildPath
exit 0
}
}

# not found
exit 1
Loading